MonadFail proposal (MFP): Moving fail out of Monad

Wolfgang Jeltsch g9ks157k at acme.softbase.org
Thu Jun 11 15:58:19 UTC 2015


Ah, I see. Even if you desugar pattern matching against (_, _) in a do
block like you do for multi-constructor data types, ⊥ still does not
result in an invocation of fail, since matching ⊥ against (_, _) leads
to divergence. To illustrate this, let f be defined as follows:

    f (_, _) = True
    f _      = False

Applying f to an expression of the form (x, y) results in True, applying
it to ⊥ results in ⊥. False can never be the result.

That said, it would seem more logical to me if all data types would be
treated equal in monadic pattern matching.

All the best,
Wolfgang

Am Donnerstag, den 11.06.2015, 11:36 -0400 schrieb David Feuer:
> Pattern matching on `undefined` is not like pattern match failure.
> Single-constructor types are only special if they're unlifted:
> `newtype` and GHC's unboxed tuples are the only examples I know of,
> and you can't use unboxed tuples in this context.
> 
> On Thu, Jun 11, 2015 at 11:28 AM, Wolfgang Jeltsch
> <g9ks157k at acme.softbase.org> wrote:
> > Are you sure that desugaring works this way? If yes, this should be
> > considered a bug and be fixed, I would say. It is very illogical.
> >
> > All the best,
> > Wolfgang
> >
> > Am Donnerstag, den 11.06.2015, 16:23 +0100 schrieb David Turner:
> >> 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 <g9ks157k at 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 at haskell.org
> >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
> >
> >
> > _______________________________________________
> > Libraries mailing list
> > Libraries at haskell.org
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries




More information about the ghc-devs mailing list