Skip to content
Snippets Groups Projects

Add MRaise typeclass

Closed Thibaut Pérami requested to merge tperami/stdpp:mraise into master
5 unresolved threads

This is an alternative to MFail in #488. It allows a monad to present a general error raising mechanism. This includes an example instantiation for option. I didn't do the work of #488 to completely replace MGuard, but if we decide to use this instead of MFail, we can merge the two patches.

Edited by Thibaut Pérami

Merge request reports

Loading
Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
1204 1204 Notation "'guard' P 'as' H ; z" := (mguard P (λ H, z))
1205 1205 (at level 20, z at level 200, only parsing, right associativity) : stdpp_scope.
1206 1206
1207 (** For any monad that had a builtin way to raise an exception *)
1208 Class MRaise (E : Type) (M : Type Type) := mraise : {A}, E M A.
  • I think I'd prefer to use the Rust Result/"error" terminology here, in which case this should probably be called MErr or MError.

  • Author Contributor

    I'm not entirely convinced "error" is a good term, because this can also be used, for example, for discarding a possible execution in a non-deterministic context (when you realize late that the current execution is actually impossible), in which case what you raise is not error. An example of this in the list monad as the most basic non-determinism monad is to return the empty list. One could have a label type "discard" and decide that mraise discard means the empty list. I intend to do something similar in my development. Although I agree this happens much less often than a regular error case.

  • std++ conventions have had some inspiration from Haskell.

    Does this thing have a name in Haskell? I see there is MonadError and throwError in https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Error.html

  • Author Contributor

    Haskell MonadError is a bit more than this, because it also allows catching errors. But the throwError part of it is exactly this proposal.

    However, the reason I liked MRaise is that all the others monadic typeclasses, MRet, MBind, and MJoin are verbs about actions that you can do with the monad, and therefore the corresponding term-level function is also a verb mret, mbind, mjoin (With "return" being abbreviated as "ret" ofc). If we keep this consistent naming, the function name would be merror which is a bit weird because it's not a verb. Doing mthrowerror or mThrowError or mRaiseError is a bit inconsistent with how all the other monads are named. I think being able to guess the typeclass term-level action from the typeclass name is a nice property that we should probably try to keep.

    Alternatively we can do MThrow and mthrow which is basically the same as MRaise but with a different verb. This has the advantage of having one verb in common with the Haskell counterpart

  • +1 for MThrow and mthrow.

  • Please register or sign in to reply
  • Thibaut Pérami mentioned in merge request !488 (closed)

    mentioned in merge request !488 (closed)

  • Thibaut Pérami changed the description

    changed the description

  • 1204 1204 Notation "'guard' P 'as' H ; z" := (mguard P (λ H, z))
    1205 1205 (at level 20, z at level 200, only parsing, right associativity) : stdpp_scope.
    1206 1206
    1207 (** For any monad that had a builtin way to raise an exception *)
    1208 Class MRaise (E : Type) (M : Type Type) := mraise : {A}, E M A.
    1209 Global Arguments mraise {_ _ _ _} _ : assert.
    1210 Global Instance: Params (@mraise) 4 := {}.
    1211 Global Hint Mode MRaise ! ! : typeclass_instances.
    1212
    1213 (** We use unit as the error content for monads that can report an error without
    1214 payload like an option *)
    1215 Definition mfail `{MRaise () M} {A} : M A := mraise ().
    1216
    1217 (** mguard or, like mguard but one can specify the error in case of failure *)
    1218 Definition mguard_or `{MRaise E M} P {dec : Decision P} {A}
    1219 (e : E) (f : P M A) : M A :=
  • 1204 1204 Notation "'guard' P 'as' H ; z" := (mguard P (λ H, z))
    1205 1205 (at level 20, z at level 200, only parsing, right associativity) : stdpp_scope.
    1206 1206
    1207 (** For any monad that had a builtin way to raise an exception *)
    1208 Class MRaise (E : Type) (M : Type Type) := mraise : {A}, E M A.
    1209 Global Arguments mraise {_ _ _ _} _ : assert.
    1210 Global Instance: Params (@mraise) 4 := {}.
    1211 Global Hint Mode MRaise ! ! : typeclass_instances.
    1212
    1213 (** We use unit as the error content for monads that can report an error without
    1214 payload like an option *)
    1215 Definition mfail `{MRaise () M} {A} : M A := mraise ().
  • 1215 Definition mfail `{MRaise () M} {A} : M A := mraise ().
    1216
    1217 (** mguard or, like mguard but one can specify the error in case of failure *)
    1218 Definition mguard_or `{MRaise E M} P {dec : Decision P} {A}
    1219 (e : E) (f : P M A) : M A :=
    1220 match decide P with
    1221 | left p => f p
    1222 | right _ => mraise e
    1223 end.
    1224 Notation "'guard' P 'or' e ; z" := (mguard_or P e (λ _, z))
    1225 (at level 20, z at level 200, only parsing, right associativity) : stdpp_scope.
    1226 Notation "'guard' P 'or' e 'as' H ; z" := (mguard_or P e (λ H, z))
    1227 (at level 20, z at level 200, only parsing, right associativity) : stdpp_scope.
    1228
    1229 (* mfail replaces MGuard *)
    1230 Global Instance mguard_mfail `{MRaise () M} : MGuard M :=
  • mentioned in merge request adamAndMath/stdpp!1 (merged)

  • Thibaut Pérami mentioned in merge request !522 (merged)

    mentioned in merge request !522 (merged)

  • Author Contributor

    Replaced by #522

  • Please register or sign in to reply
    Loading