
On Mon, Sep 14, 2009 at 09:42:22PM +0300, Michael Snoyman wrote:
On Sun, Sep 13, 2009 at 3:40 PM, Brent Yorgey
wrote: On Sat, Sep 12, 2009 at 09:13:58PM +0300, Michael Snoyman wrote:
I often times have to write a lookup function that returns its value into any monad instead of just Maybe. For example:
mLookup :: (Eq k, Monad m) => k -> [(k, v)] -> m v mLookup k pairs = case lookup k pairs of Nothing -> fail "mLookup: nothing found" Just v -> return v
This is actually the type that the lookup function USED to have, but it was changed since monads actually have nothing to do with failing (the fail method is just a hack used to handle pattern-match failures in do-notation). Probably a better implementation of this would be
mLookup :: (Eq k, MonadPlus m) => k -> [(k,v)] -> m v mLookup k pairs = maybe mzero return (lookup k pairs)
I understand that fail being in Monad is controversial, but my version of the function works in *all* monads. This is very useful for:
It doesn't work in *all* monads -- it only works in monads which support a sensible notion of failure. This is exactly what is captured by the MonadPlus constraint on my version of mLookup. And, in fact, any monad in context of which you would want to use mLookup (IO, Maybe, [], ...) are already instances of MonadPlus. Also, fail being in Monad isn't controversial, it's just wrong. =) The only controversial thing is what to DO about it now that it's there... -Brent