I'm trying to implement a function which usually puts the first element of a list in a monad, but if the monad is a list it returns the whole list:
putInMonad :: MonadPlus m => [a] -> m a
putInMonad (s:sx) = return s
putInMonad _ = mzero
putInMonad [1,2,3] :: Maybe Int
Should return Just 1
, and
putInMonad [1,2,3] :: [] Int
should return [1,2,3]
.
Any ideas?
In your particular use-case, you could take advantage of msum
:
putInMonad :: MonadPlus m => [a] -> m a
putInMonad x = msum $ map return x
Then both examples will work:
% putInMonad [1,2,3,4] :: Maybe Int
Just 1
% putInMonad [1,2,3,4] :: [Int]
[1,2,3,4]
Note however that Maybe
is not exactly MonadPlus
, since mplus
there is not associative.