Haskell monad进入monad

时间:2017-11-30 01:52:04

标签: haskell monads

方法(>>=) :: forall a b. m a -> (a -> m b) -> m b。 我如何制作方法:: forall a b. m (n a) -> (a -> m (n b)) -> m (n b),其中m和n是monad。

2 个答案:

答案 0 :(得分:0)

正如PyRulez所写,对此没有通用的解决方案,但鉴于您报告的类型,以下内容应该有效。

你需要

import Control.Monad (join)

使用do表示法,您可以撰写两个函数foobar,如下所示:

comp :: (a -> TargetClient (MethodResult b)) ->
        (b -> TargetClient (MethodResult c)) ->
         a -> TargetClient (MethodResult c)
comp foo bar x = do
  f <- foo x
  b <- join <$> traverse bar f
  return b

如果您不喜欢do表示法,可以将其全部缩减至:

comp' :: (a -> TargetClient (MethodResult b)) ->
         (b -> TargetClient (MethodResult c)) ->
          a -> TargetClient (MethodResult c)
comp' foo bar x = foo x >>= fmap join . traverse bar

当您使用f映射bar时,您将会以错误的顺序堆叠monad,可以这么说,但您可以使用traverse来切换堆栈。即使你这样做,Either中也会有一个Either,这就是你需要join的原因。

答案 1 :(得分:0)

如果mn都是monad,那么您还需要一个额外的部分来使复合m.n成为monad。

所需要的是一种“分配法则”,即一种自然的态射 forall a . n(m a) -> m(n a)(请参阅here它来自Beck,也用于街道)

然后很容易编写缺失的部分并验证它是否符合monad法则。