在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
然而有些事情是不对的......有人能指出什么吗?
答案 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
。