No. It's impossible. However, you can write a function with a signature:
findM :: Monad m => (a -> m Bool) -> m [a] -> m (Maybe a)
The reason is impossible, because in order to find out if Maybe has a Just x or Nothing constructor, you must get the value from the monad. This means that Maybe should be inside the monad at the end, since it is generally impossible to extract the value from within the monad. (After all, these are all monads).
For example, if your signature matches findM , you can write some obviously incorrect functions:
findM :: Monad m => (a -> m Bool) -> m [a] -> Maybe (ma) findM = magic anyM :: Monad m => (a -> m Bool) -> m [a] -> Bool anyM f = isJust . findM f extractBool :: Monad m => m Bool -> Bool extractBool = anyM id . liftM (:[])
The extractBool function is obviously not possible, so findM cannot have such a signature.
Here is the findM implementation:
findM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a) findM _ [] = return Nothing findM f (x:xs) = do y <- fx if y then return (Just x) else findM f xs
I'm not sure about a simpler way to implement it - it seems pretty clean and it works with infinite lists.
Changing the signature with m [a] to use [a] makes it more useful and easier to use. You will quickly understand why if you implement both interfaces.
source share