AIUI the point about ⊥ and (⊥, ⊥) being different doesn't matter here: a bind for a single-constructor datatype never desugars in a way that uses fail (which isn't to say that it can't be undefined)
For instance: runErrorT (do { (_,_) <- return undefined; return () } :: ErrorT String IO ()) throws an exception, even though the bind is in ErrorT where fail just returns left: runErrorT (do { fail "oops"; return () } :: ErrorT String IO ()) => Left "oops" Hope that helps, and hope I understand correctly! David On 11 June 2015 at 16:08, Wolfgang Jeltsch <g9ks1...@acme.softbase.org> wrote: > Hi David, > > thank you very much for this proposal. I think having fail in Monad is > just plain wrong, and I am therefore very happy to see it being moved > out. > > I have some remarks, though: > >> A class of patterns that are conditionally failable are `newtype`s, >> and single constructor `data` types, which are unfailable by >> themselves, but may fail if matching on their fields is done with >> failable paterns. > > The part about single-constructor data types is not true. A > single-constructor data type has a value ⊥ that is different from > applying the data constructor to ⊥’s. For example, ⊥ and (⊥, ⊥) are two > different values. Matching ⊥ against the pattern (_, _) fails, matching > (⊥, ⊥) against (_, _) succeeds. So single-constructor data types are not > different from all other data types in this respect. The dividing line > really runs between data types and newtypes. So only matches against > patterns C p where C is a newtype constructor and p is unfailable should > be considered unfailable. > >> - Applicative `do` notation is coming sooner or later, `fail` might >> be useful in this more general scenario. Due to the AMP, it is >> trivial to change the `MonadFail` superclass to `Applicative` >> later. (The name will be a bit misleading, but it's a very small >> price to pay.) > > I think it would be very misleading having a MonadFail class that might > have instances that are not monads, and that this is a price we should > not pay. So we should not name the class MonadFail. Maybe, Fail would be > a good name. > >> I think we should keep the `Monad` superclass for three main reasons: >> >> - We don't want to see `(Monad m, MonadFail m) =>` all over the place. > > But exactly this will happen if we change the superclass of (Monad)Fail > from Monad to Applicative. So it might be better to impose a more > light-weight constraint in the first place. Functor m might be a good > choice. > > All the best, > Wolfgang > > _______________________________________________ > ghc-devs mailing list > ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs