简体   繁体   English

f, g, h :: Kleisli ((->) e) ab <=> f >>> (g &&& h) = (f >>> g) &&& (f >>> h)?

[英]f, g, h :: Kleisli ((->) e) a b <=> f >>> (g &&& h) = (f >>> g) &&& (f >>> h)?

Edit: We will call an arrow p pure if exists such function f that: p = arr f .编辑:如果存在这样的函数f ,我们将调用箭头p pure: p = arr f

I'm trying to get a better grasp of Arrows in Haskell, and I want to figure out when我试图更好地掌握 Haskell 中的 Arrows,我想弄清楚什么时候

f >>> (g &&& h) = (f >>> g) &&& (f >>> h) , where f , g , h are arrows. f >>> (g &&& h) = (f >>> g) &&& (f >>> h) ,其中f , g , h是箭头。

Obviously, it isn't generally true.显然,这通常不是真的。 In this particular example, the side-effects are duplicated on the right hand:在这个特定的例子中,副作用在右手边重复:

GHCi> c = Kleisli $ \x -> ("AB", x + 1)
GHCi> fst . runKleisli (c >>> c &&& c) $ 1
"ABABAB"
GHCi> fst . runKleisli ((c >>> c) &&& (c >>> c)) $ 1
"ABABABAB"

Obviously, f >>> (g &&& h) = (f >>> g) &&& (f >>> h) if f is pure.显然, f >>> (g &&& h) = (f >>> g) &&& (f >>> h)如果f是纯的。

I was experimenting in GHCi with this statement for f, g, h :: Kleisli ((->) e) ab , and didn't manage to find such values of f , g and h that f >>> (g &&& h) ≠ (f >>> g) &&& (f >>> h) .我在 GHCi 中用f, g, h :: Kleisli ((->) e) ab这个语句试验,并没有设法找到f , gh这样的值f >>> (g &&& h) ≠ (f >>> g) &&& (f >>> h) Is this statement indeed true for f, g, h :: Kleisli ((->) e) ab , and, if so, could this be a valid proof of that: The effect of the Monad ((->) e) is reading from the environment.对于f, g, h :: Kleisli ((->) e) ab ,这个陈述是否真的正确,如果是这样,这是否是一个有效的证明: Monad ((->) e)是从环境中读取。 Thus, the result of the application of f is the function with the help of which g and h are going to read from the environment.因此,应用f的结果是gh将从环境中读取的函数。 No matter where this function was created – it is the same since it is applied to the same argument every time, thus the result of reading from the environment is the same, thus the overall result is the same as well.无论这个函数在哪里创建 - 它都是一样的,因为它每次都应用于相同的参数,因此从环境中读取的结果是相同的,因此整体结果也是相同的。

Intuitively直观地

Yes, the (->) e monad is a reader monad, and it does not matter if we perform two reads or only one.是的, (->) e monad 是一个 reader monad,我们执行两次读取还是只执行一次都没有关系。 Running f once or twice does not matter, since it will always produce the same result, with the same effect (reading).运行f一次或两次无关紧要,因为它总是会产生相同的结果,具有相同的效果(读取)。

Your reasoning seems intuitively correct to me.你的推理在我看来直觉上是正确的。

Formally正式地

f, g, h :: Kleisli ((->) e) ab essentially means f, g, h :: a -> (e -> b) , removing the wrapper. f, g, h :: Kleisli ((->) e) ab本质上意味着f, g, h :: a -> (e -> b) ,移除包装器。

Again, ignoring the wrapper, we get再次忽略包装器,我们得到

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))

Hence:因此:

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'))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM