如何处理IO(Maybe(IO(Maybe t)))类型?

时间:2016-08-02 18:22:26

标签: haskell composition monad-transformers

我正在处理一个库(ghcjs-dom),其中每个函数都返回一个IO (Maybe T)

我有一个函数a,返回IO (Maybe x)和函数b,它将x作为参数并返回IO (Maybe y)

是否允许我执行a ??? b并获得IO (Maybe y)的运算符。我的Hoogle搜索没有任何结果。

我看起来像join,适用于IO (Maybe (IO (Maybe t)))而不是IO (IO t)Maybe (Maybe t)

2 个答案:

答案 0 :(得分:10)

根据我的理解,你有:

a :: IO (Maybe X)
b :: X -> IO (Maybe Y)

IO (Maybe a)MaybeT IO a之间存在密切关系,即MaybeT将一个转换为另一个:

MaybeT :: IO (Maybe a) -> MaybeT IO a

,反向操作只是runMaybeT

runMaybeT :: MaybeT IO a -> IO (MaybeT a)

在MaybeT monad中,你想要表演的作品就是 绑定操作:

MaybeT a >>= (\x -> MaybeT (b x)) :: MaybeT IO Y

这会产生MaybeT IO Y类型的值。要将其转换回IO (Maybe Y),只需使用runMaybeT

<强>更新

以下是&#34;撰写&#34; a b

andThen :: IO (Maybe a) -> (a -> IO (Maybe b)) -> IO (Maybe b)
andThen a b = runMaybeT $  MaybeT a >>= (\x ->  MaybeT (b x) )

但是,如果你发现自己经常使用这个操作符,也许你 应该修改你的功能,这样你才能主要在MaybeT IO工作 monad,然后你只需使用>>=一个runMaybeT 在外面。

答案 1 :(得分:3)

如果您不想使用MaybeTsequenceAtraverse来自Data.Traversable

Prelude Data.Traversable Control.Monad> :t fmap join . join . fmap sequenceA 

fmap join . join . fmap sequenceA
  :: (Traversable m, Control.Applicative.Applicative f, Monad m,
      Monad f) =>
      f (m (f (m a))) -> f (m a)

在你的情况下,f是IO,m可能。