当函数使用IO时,可能使用fmap

时间:2014-02-14 06:45:54

标签: haskell

我有一个函数,我想使用Maybe val。通常我会做func <$> val。但现在假设func使用IO monad。 func <$> val将返回Maybe (IO ())。所以我必须定义一个新的运算符:

(<$$>) :: Monad m => (a -> m b) -> Maybe a -> m ()
(<$$>) func (Just val) = func val >> return ()
(<$$>) func Nothing    = return ()

所以现在我可以写func <$$> val,但还有更好的方法吗?

4 个答案:

答案 0 :(得分:3)

来自Data.Foldable

mapM_可能是最佳匹配:

Prelude Data.Foldable> :set -XScopedTypeVariables
Prelude Data.Foldable> :t \f (a :: Maybe a) -> Data.Foldable.mapM_ f a
\f (a :: Maybe a) -> Data.Foldable.mapM_ f a
  :: Monad m => (a -> m b) -> Maybe a -> m ()

如果您想要更专业的类型,还有maybe

Prelude> :t \f -> maybe (return ()) (f $)
\f -> maybe (return ()) (f $)
  :: Monad m => (a -> m ()) -> Maybe a -> m ()

答案 1 :(得分:1)

<$$> Data.Foldable traverse_来自{{1}}。

答案 2 :(得分:0)

单线总是更好吗?以下是undefined的纯度有用的方法:

(<$$>) g x = maybe (return undefined) g x >> return ()

示例:

 Prelude> print <$$> (Just 1)
 1
 Prelude> print <$$> Nothing
 Prelude>

答案 3 :(得分:0)

如果您的代码中包含大量内容,则可能值得使用MaybeT transformer

   (\func val -> liftIO . func =<< MaybeT (return val) ) 
        :: (a -> IO b) -> Maybe b -> MaybeT IO b

这并不能立即为你带来明显的IO (Maybe ()),但它的组成很好。