繁体   English   中英

Haskell monad变成monad

[英]Haskell monad into monad

有方法(>>=) :: forall a b. ma -> (a -> mb) -> mb (>>=) :: forall a b. ma -> (a -> mb) -> mb 我该如何制作方法:: forall a b. m (na) -> (a -> m (nb)) -> m (nb) :: forall a b. m (na) -> (a -> m (nb)) -> m (nb) ,其中m和n是单子。

正如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

bar映射f时,可以说单子堆叠的顺序错误,但是可以使用traverse切换堆叠。 即使这样做,您也会在Either中拥有一个Either ,因此这就是您需要join的原因。

如果mn都是单子,则还需要另外一块使合成mn成为单子。

所需要的是“分布定律”,即对所有a的自然态forall a . n(ma) -> m(na) forall a . n(ma) -> m(na) (请参阅此处,它来自Beck,也用于Street)

这样就很容易写出丢失的部分并验证其是否满足单子法则。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM