On Sat, Dec 05, 2009 at 02:13:10PM -0800, Gregory Crosswhite wrote: > > The problem comes from the fact that >>= takes a *function* as its > second argument, and so if the first argument is an error then we > can't evaluate the second argument in order to see if it has an > error as well.
Hmm, that's true. I guess I misspoke about liftM2 (+) being able to collect both error messages. > instance Functor E where > fmap _ (E (Left error)) = E (Left error) > fmap f (E (Right argument)) = E (Right (f argument)) > > instance Applicative E where > pure = E . Right > (<*>) (E (Left error2)) (E (Left error1)) = E (Left (error1 ++ error2)) > (<*>) (E (Left error)) _ = E (Left error) > (<*>) _ (E (Left error)) = E (Left error) > (<*>) (E (Right function)) (E (Right argument)) = E (Right (function > argument)) OK, this looks like a perfectly valid Applicative instance for E (it satisfies the Applicative laws). So what we have here, it seems, is a type with at least two reasonable Applicative instances, one of which does *not* correspond to a Monad instance. My argument is that it is very strange (I might even go so far as to call it a bug) to have a type with an Applicative instance and a Monad instance which do not correspond, in the sense that pure = return (<*>) = ap although I certainly understand the motivation in this case. Hmm, I'll have to think about this a bit more. The Monad instance which tries passing undefined to the right-hand side of >>= if the left-hand side is an error is strangely compelling, if semantically unsound... -Brent _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
