我有一个函数,我想使用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
,但还有更好的方法吗?
答案 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 ())
,但它的组成很好。