定义Monad运算符

时间:2015-10-16 00:26:21

标签: haskell monads

在Haskell的Monads中,我可以轻松地将运算符(>=>)定义为:

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
f >=> g = \x -> f x >>= g

我也知道(>>=)可以使用(>=>)来表达:我们将(>>=)称为(..)

(..) :: Monad m => m a -> (a -> m b) -> m b
m .. k = m >=> \_ -> k

然而有些事情是不对的......有人能指出什么吗?

2 个答案:

答案 0 :(得分:9)

使用常量函数(即\_ -> -- etc.)从一个函数中创建一个函数的想法,这个函数不是一个函数,因此你可以把它传递给(>=>)。只有两个问题。首先,你正在做错误的论证,因为一个不是函数的是m

GHCi> :t \m k -> (\_ -> m) >=> k
\m k -> (\_ -> m) >=> k :: Monad m => m b -> (b -> m c) -> a -> m c

其次,(>=>)为您提供了一个函数(在上面的演示中类型为a -> m c)。您必须将其应用于某些内容才能获得与(>>=)匹配的结果类型。由于这个论点是无关紧要的(你最终将它提供给一个常数函数),你可以使用()

GHCi> :t \m k -> ((\_ -> m) >=> k) ()
\m k -> ((\_ -> m) >=> k) () :: Monad m => m b -> (b -> m c) -> m c

就是这样。我发现使用const函数而不是编写\_ ->稍微漂亮一点,所以我会把它写成:

(>>..) :: Monad m => m a -> (a -> m b) -> m b
m >>.. k = (const m >=> k) ()

答案 1 :(得分:2)

解决方案如下:

(..) :: Monad m => m a -> (a -> m b) -> m b
m .. k =
  (const m >=> k) undefined

使用const我们将m a类型的操作解除为whatever -> m a。这个提升版本没有给出一个该死的,我们传递给它的所以它也可能是undefined