【问题标题】:What is the name of the monadic "versions" of fmap?fmap 的一元“版本”的名称是什么?
【发布时间】:2017-08-19 19:50:29
【问题描述】:

拥有 powershell 脚本的背景,我首先认为以管道的方式来考虑函数组合是很自然的。这意味着组合的语法应该是 fun1 | fun2 | fun3 以一种伪代码的方式。 (其中fun[i] 是按顺序应用的i'th 函数)。这个函数顺序也是你在 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 定义为带有参数的运算符,其顺序感觉倒退?

【问题讨论】:

  • 您的mmap=<<,这并不奇怪。 Monadic bind 不类似于函数组合;它更像是函数应用程序。
  • 关于应用程序/组合 chepner 的要点。我最终切换到 Kliesli 组合(

标签: haskell monads functor


【解决方案1】:

是否已经定义了mmap?叫什么?

Hoogle 是你的朋友。 (>>=) 的类型签名是:

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

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

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

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

为什么将 bind 定义为带有参数的运算符,其顺序感觉倒退?

这是因为一元代码看起来很像命令式代码。例如,考虑以下情况:

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)

看到相似之处了吗?如果我们改用=&lt;&lt;,它看起来像:

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

不是很可读吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    相关资源
    最近更新 更多