也许将函数应用于 IO 中的值



我有一个类型a -> IO (Maybe b)的函数,我想将其应用于IO (Maybe a)并得到IO (Maybe b)。我写了一个函数来做到这一点:

ioMaybeApply :: (a -> IO (Maybe b)) -> IO (Maybe a) -> IO (Maybe b)
ioMaybeApply f ioMaybeA = do
maybeA <- ioMaybeA
maybe (return Nothing) f maybeA

有没有标准的Haskell函数来做到这一点?我尝试使用Hoogle搜索,但一无所获。如果不是,我的实现是好的,还是更简单?

这可以通过MaybeTmonad 变压器来实现:

GHCi> import Control.Monad.Trans.Maybe
GHCi> :t f m -> runMaybeT (MaybeT m >>= MaybeT . f)
f m -> runMaybeT (MaybeT m >>= MaybeT . f)
:: Monad m => (a1 -> m (Maybe a)) -> m (Maybe a1) -> m (Maybe a)
import Control.Monad.Trans.Maybe
-- Making it look like your definition, for the sake of comparison.
ioMaybeApply :: (a -> IO (Maybe b)) -> IO (Maybe a) -> IO (Maybe b)
ioMaybeApply f ioMaybeA = runMaybeT $ do
a <- MaybeT ioMaybeA
MaybeT (f a)

如果您在多个地方使用此模式,那么将a -> IO (Maybe b)函数更改为a -> MaybeT IO b可能会有所回报 - 然后您可以使用(>>=)和/或无缝的do-block而不是专用函数。另一方面,如果这只是一次性的,您可能会合理地认为使用MaybeT是矫枉过正的;在这种情况下,您的实现完全没问题。

(值得一提的是,虽然有一个名为Compose的嵌套函子的通用包装器具有FunctorApplicative个实例,但它没有Monad实例,因为嵌套两个 monad 并不一定会产生可以给出合法Monad实例的东西。既然如此,我们通常采用为每种有效的组合量身定制的单变压器。

最新更新