我遇到了一些简短的单子(monad)代码,我有一个与示例的实际主题无关的问题
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap mf mx = do
f <- mf
x <- mx
return (f x)
保持纯粹的象征性,而不知道所有上下文或代码“做什么”,上面相当于
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap mf mx = do
x <- mx
f <- mf
return (f x)
当我第一次看到示例代码时,我想知道这段代码的作者是否有意识地选择顺序 f <- mf, x <-mx 而不是 x <- mx, f <- mf 是否有原因,因为顺序确实有影响,或者完全是任意的。
致以诚挚的问候
冈瑟
最佳答案
不,它们并不等同。脱糖后,它们是
mf >>= (\f -> mx >>= (\x -> return (f x)))
mx >>= (\x -> mf >>= (\f -> return (f x)))
因此,在第一个定义中,绑定(bind)操作首先应用于 mf
,然后应用于 mx
,而在第二个定义中则相反。 Bind 不是可交换的,或者至少不需要(单子(monad)定律不要求这样做)。不涉及 IO 的反例是 mf = [(+1), (+2)]
、mx = [1, 5]
。
关于haskell - 这些一元表达式是否等价,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26142878/