haskell - 这些一元表达式是否等价

标签 haskell monads

我遇到了一些简短的单子(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/

相关文章:

haskell - 在 Haskell 中从字符映射到字符串

haskell - 仅当文件不存在时如何创建文件

haskell - “Template Haskell + C” 错误的解决方法?

haskell - 这个语句中的类型是如何解析的

haskell - <- 是否隐式强制 Haskell do block 中的类型?

haskell - 消息框错误 : foreign import unsafe

haskell - 获取匹配长度(秒差距)

haskell - 为什么 Haskell 异常只能在 IO monad 中捕获?

haskell - 用延续单子(monad)向前跳跃

haskell - 暂停单子(monad)