Zhi*_*gor 5 monads haskell arrows kleisli reader-monad
编辑:p如果存在以下功能f,我们将调用纯箭头:p = arr f。
我试图更好地了解Haskell中的Arrows,我想弄清楚何时
f >>> (g &&& h) = (f >>> g) &&& (f >>> h)其中f,g,h是箭头。
显然,通常情况并非如此。在此特定示例中,副作用在右侧重复:
GHCi> c = Kleisli $ \x -> ("AB", x + 1)
GHCi> fst . runKleisli (c >>> c &&& c) $ 1
"ABABAB"
GHCi> fst . runKleisli ((c >>> c) &&& (c >>> c)) $ 1
"ABABABAB"
Run Code Online (Sandbox Code Playgroud)
显然,f >>> (g &&& h) = (f >>> g) &&& (f >>> h)如果f是纯净的。
我在尝试GHCI这个语句f, g, h :: Kleisli ((->) e) a b,并没有设法找到这样的价值观f,g和h那个f >>> (g &&& h) ? (f >>> g) &&& (f >>> h)。此声明确实适用于f, g, h :: Kleisli ((->) e) a b,如果是这样,是否可以有效证明这一点:的影响Monad ((->) e)是从环境中读取数据。因此,的应用结果f就是该功能的帮助,g并将h从环境中读取该功能。无论在何处创建此函数,它都是一样的,因为每次都将其应用于相同的参数,因此从环境中读取的结果是相同的,因此总体结果也相同。
是的,该(->) emonad 是一个读取器 monad,我们执行两次读取或仅执行一次读取并不重要。运行f一次或两次并不重要,因为它总是会产生相同的结果,具有相同的效果(阅读)。
在我看来,你的推理直观上是正确的。
f, g, h :: Kleisli ((->) e) a b本质上意味着f, g, h :: a -> (e -> b),去除包装纸。
再次忽略包装,我们得到
for all (f :: a -> e -> b) and (g :: b -> e -> c)
f >>> g = (\xa xe -> g (f xa xe) xe)
for all (f :: a -> e -> b) and (g :: a -> e -> c)
f &&& g = (\xa xe -> (f xa xe, g xa xe))
Run Code Online (Sandbox Code Playgroud)
因此:
f >>> (g &&& h)
= { def &&& }
f >>> (\xa xe -> (g xa xe, h xa xe))
= { def >>> }
(\xa' xe' -> (\xa xe -> (g xa xe, h xa xe)) (f xa' xe') xe')
= { beta }
(\xa' xe' -> (g (f xa' xe') xe', h (f xa' xe') xe'))
(f >>> g) &&& (f >>> h)
= { def >>> }
(\xa xe -> g (f xa xe) xe) &&& (\xa xe -> h (f xa xe) xe)
= { def &&& }
(\xa' xe' -> ((\xa xe -> g (f xa xe) xe) xa' xe', (\xa xe -> h (f xa xe) xe) xa' xe'))
= { beta }
(\xa' xe' -> (g (f xa' xe') xe', h (f xa' xe') xe'))
Run Code Online (Sandbox Code Playgroud)