如何处理 IO (Maybe (IO (Maybe t))) 类型?
How to deal with an IO (Maybe (IO (Maybe t))) type?
我正在处理一个库 (ghcjs-dom
),其中每个函数 returns 一个 IO (Maybe T)
。
我有一个函数 a
和 returns 一个 IO (Maybe x)
和函数 b
以 x
作为参数和 returns 一个IO (Maybe y)
.
是一个运算符,可以让我执行 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
.
更新
这里是 "compose" 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
在外面。
如果您不想使用 MaybeT
,您需要 sequenceA
或 traverse
来自 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 可能。
我正在处理一个库 (ghcjs-dom
),其中每个函数 returns 一个 IO (Maybe T)
。
我有一个函数 a
和 returns 一个 IO (Maybe x)
和函数 b
以 x
作为参数和 returns 一个IO (Maybe y)
.
是一个运算符,可以让我执行 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
.
更新
这里是 "compose" 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
在外面。
如果您不想使用 MaybeT
,您需要 sequenceA
或 traverse
来自 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 可能。