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

Reply via email to