Reputation: 15872
I have a function that I want to use a Maybe
val with. Usually I would do func <$> val
. But now suppose that func
uses the IO monad. func <$> val
will return a Maybe (IO ())
. So instead I had to define a new operator:
(<$$>) :: Monad m => (a -> m b) -> Maybe a -> m ()
(<$$>) func (Just val) = func val >> return ()
(<$$>) func Nothing = return ()
So now I can write func <$$> val
, but is there a better way to do it?
Upvotes: 5
Views: 267
Reputation: 29100
mapM_
from Data.Foldable
is probably the best match:
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 ()
If you'd like a more specialised type there's also maybe
:
Prelude> :t \f -> maybe (return ()) (f $)
\f -> maybe (return ()) (f $)
:: Monad m => (a -> m ()) -> Maybe a -> m ()
Upvotes: 3
Reputation: 120711
If you have a lot of this in your code, it might be worth employing the MaybeT
transformer:
(\func val -> liftIO . func =<< MaybeT (return val) )
:: (a -> IO b) -> Maybe b -> MaybeT IO b
That doesn't immediately bring you any further than plain IO (Maybe ())
, but it composes nicely.
Upvotes: 0
Reputation: 5406
Is a one-liner always better? Here's how purity of undefined
can be useful:
(<$$>) g x = maybe (return undefined) g x >> return ()
Example:
Prelude> print <$$> (Just 1)
1
Prelude> print <$$> Nothing
Prelude>
Upvotes: 0