
On 8 March 2012 21:43, Brent Yorgey
‘Course "fail" is suboptimal and MonadError might be better.
Monads have nothing to do with failure. Instead of Monad you would want to use something like MonadZero or MonadError.
Yeah that's what I said. GOSH. </NapoleanDynamite>
However, these are also suboptimal because in monads which carry extra information about the failure (i.e. anything other than [] or Maybe), the lookup function now has to make up an error message, when it almost certainly it doesn't know enough to give a good one.
Good point! I had sort of felt this way regarding the monadic return in the past, but thought there might be some hidden wisdom behind the idea that I hadn't seen, and why it was in some base libraries some time back. Hadn't paid much attention to it, though. Indeed, the lookup function can't show the key to provide a useful exception message. Another problem, even if you make it like lookup :: MonadError (LookupError key) m => key -> collection -> m a, there's still the problem that the error isn't polymorphic in the same monad, so if lookup throws e :: LookupError the whole monad needs to be that because the functional dep is m -> e. Making MonadError kinda pointless. MonadZero gives no information and can't be handled trivially like Maybe, too.
This is why the use of Maybe is encouraged: Maybe is the *initial* instance of MonadZero, so you can map from it to failure in whatever monad you happen to be using. Instead of being an annoyance this is encouraged style, because in doing the conversion *you* get to pick a meaningful error message.
Good points. I already use the fromMaybe style for this with lookup and such-like. Thanks for clarifying some things!