implementing a "findM" in Haskell?
I am looking for a function that basically is like mapM on a list -- it
performs a series of monadic actions taking every value in the list as a
parameter -- and each monadic function returns m (Maybe b). However, I
want it to stop after the first parameter that causes the function to
return a Just value, not execute any more after that, and return that
value.
Well, it'll probably be easier to just show the type signature:
findM :: (Monad m) => (a -> m (Maybe b)) -> [a] -> m (Maybe b)
where b is the first Just value. The Maybe in the result is from the
finding (in case of an empty list, etc.), and has nothing to do with the
Maybe returned by the Monadic function.
I can't seem to implement this with a straightforward application of
library functions. I could use
findM f xs = fmap (fmap fromJust . find isJust) $ mapM f xs
which will work, but I tested this and it seems that all of the monadic
actions are executed before calling find, so I can't rely on laziness
here.
ghci> findM (\x -> print x >> return (Just x)) [1,2,3]
1
2
3
-- returning IO (Just 1)
What is the best way to implement this function that won't execute the
monadic actions after the first "just" return? Something that would do:
ghci> findM (\x -> print x >> return (Just x)) [1,2,3]
1
-- returning IO (Just 1)
or even, ideally,
ghci> findM (\x -> print x >> return (Just x)) [1..]
1
-- returning IO (Just 1)
No comments:
Post a Comment