fmap 的 monadic "versions" 的名称是什么?

What is the name of the monadic "versions" of fmap?

有 powershell 脚本的背景,我首先认为以管道的方式考虑函数组合是很自然的。这意味着组合的语法应该是 fun1 | fun2 | fun3 以一种伪代码的方式。 (其中 fun[i] 是按顺序应用的第 i 个函数)。这种函数顺序也是您在 haskell monadic 绑定中找到的。 fun1 >>= fun2 >>= fun3.

但在haskell中的其他场合,函数的顺序更数学化,例如fun3 . fun2 . fun1,或者在函数设置中fmap fun3 . fmap fun2 . fmap fun1.

我很清楚这两个例子中的函数有不同的签名,但令我困惑的是结构是颠倒的,仍然。我的解决方法是有时定义一个函数 mmap = flip (>>=) 这样我就可以写 mmap fun3 . mmap fun2 . mmap fun1.

所以对于这个问题:

  1. 是否已经定义了 mmap?什么叫做?
  2. 为什么 bind 被定义为一个运算符,其参数的顺序让人感觉倒退?

Is there a mmap already defined? What is is called?

Hoogle is your friend. The type signature of (>>=) 是:

(>>=) :: Monad m => m a -> (a -> m b) -> m b

因此,您正在寻找具有类型签名的函数:

flip (>>=) :: Monad m => (a -> m b) -> m a -> m b

这实际上是 =<< 函数。因此,你可以写 fun3 =<< fun2 =<< fun1.

Why is bind defined as an operator with arguments in an order that feels backwards?

这是因为单子代码看起来很像命令式代码。例如,考虑以下内容:

permute2 :: [a] -> [[a]]
permute2 xs = do
    x  <- xs
    xs <- map return xs
    return (x:xs)

如果没有 do 的语法糖,它将被写成:

permute2 :: [a] -> [[a]]
permute2 xs =
    xs >>= \x ->
    map return xs >>= \xs ->
    return (x:xs)

看到相似之处了吗?如果我们使用 =<< 代替它看起来像:

permute2 :: [a] -> [[a]]
permute2 xs = (\x -> (\xs -> return (x:xs)) =<< map return xs) =<< xs

不是很可读吗?