[英]How to deal with an IO (Maybe (IO (Maybe t))) type?
我正在处理一个库( ghcjs-dom
),其中每个函数都返回一个IO (Maybe T)
。
我有一个函数a
返回一个IO (Maybe x)
和函数b
,它以x
作为参数并返回一个IO (Maybe y)
。
是一个让我做的操作员a ??? b
a ??? b
并获得一个IO (Maybe y)
。 我的Hoogle搜索没有任何结果。
我看起来像join
适用于IO (Maybe (IO (Maybe t)))
而不是IO (IO t)
或者Maybe (Maybe t)
。
根据我的理解,你有:
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
。
更新
这是一个“撰写” 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
使用这个操作符,也许你应该重新设计你的函数,这样你主要在MaybeT IO
monad中工作,然后你就可以在外面使用>>=
一个runMaybeT
。
如果你不想使用MaybeT
,你需要的是sequenceA
或从Data.Traversable
traverse
。
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 Maybe。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.