在powershell脚本编写方面有一个背景我首先想到以管道方式思考函数组合是很自然的。这意味着组合的语法应该以psudocode的方式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
。
所以问题是:
mmap
?什么叫做?答案 0 :(得分:7)
是否已定义
mmap
?什么叫做?
(>>=) :: Monad m => m a -> (a -> m b) -> m b
因此,您正在寻找具有类型签名的函数:
flip (>>=) :: Monad m => (a -> m b) -> m a -> m b
这实际上是=<<
功能。因此,您可以写fun3 =<< fun2 =<< fun1
。
为什么bind被定义为带有参数的运算符,其顺序感觉倒退?
这是因为monadic代码看起来很像命令式代码。例如,请考虑以下事项:
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
不是很可读吗?