Contents:
Library ConCert.Execution.ResultMonad
From ConCert.Execution Require Import Monad.
Inductive result T E :=
| Ok (t : T)
| Err (e : E).
Arguments Ok {_ _}.
Arguments Err {_ _}.
Global Instance Monad_result {E} : Monad (fun T => result T E) :=
{| ret _ t := Ok t;
bind _ _ mt f :=
match mt with
| Ok t => f t
| Err e => Err e
end |}.
Global Instance MonadLaws_Monad_result {E} : MonadLaws (@Monad_result E).
Proof.
constructor.
- auto.
- intros; cbn.
destruct t; auto.
- intros; cbn.
destruct t; auto.
Qed.
Definition result_of_option {T E : Type} (o : option T) (err : E) : result T E :=
match o with
| Some a => Ok a
| None => Err err
end.
Definition option_of_result {T E : Type} (r : result T E) : option T :=
match r with
| Ok t => Some t
| Err e => None
end.
Global Instance option_to_result
{E : Type}
: MonadTrans (fun T => E -> result T E) option :=
{| lift T (opt : option T) err := @result_of_option T E opt err |}.
Global Instance result_to_option
{E : Type}
: MonadTrans option (fun T => result T E) :=
{| lift T (opt : result T E) := @option_of_result T E opt |}.
Definition unpack_result {T E : Type} (r : result T E) :=
match r return match r with
| Ok _ => T
| Err _ => E
end with
| Ok t => t
| Err e => e
end.
Definition bind_error {T E1 E2 : Type} (f : E1 -> E2) (r : result T E1) : result T E2 :=
match r with
| Ok t => Ok t
| Err e => Err (f e)
end.
Definition isOk {T E : Type} (r : result T E) :=
match r with | Ok _ => true | Err _ => false end.
Definition isErr {T E : Type} (r : result T E) :=
match r with | Ok _ => false | Err _ => true end.
Lemma result_of_option_eq_some : forall {T E : Type} (x : option T) (e : E) (y : T),
result_of_option x e = Ok y <-> x = Some y.
Proof.
split; destruct x; intros eq;
(discriminate || injection eq as <-; reflexivity).
Qed.
Lemma result_of_option_eq_none : forall {T E : Type} (x : option T) (e1 e2 : E),
result_of_option x e1 = Err e2 -> x = None.
Proof.
destruct x;
(discriminate || reflexivity).
Qed.
Lemma isOk_Ok : forall {T E : Type} (r : result T E) (x : T),
r = Ok x -> isOk r = true.
Proof.
intros.
now subst.
Qed.
Lemma isOk_Err : forall {T E : Type} (r : result T E) (e : E),
r = Err e -> isOk r = false.
Proof.
intros.
now subst.
Qed.
Lemma isOk_exists : forall {T E : Type} (r : result T E),
isOk r = true <-> exists x : T, r = Ok x.
Proof.
split.
- intros.
destruct r; eauto.
discriminate.
- intros (x & r_eq).
eapply isOk_Ok.
eauto.
Qed.
Lemma isOk_not_exists : forall {T E : Type} (r : result T E),
isOk r = false <-> forall x : T, r <> Ok x.
Proof.
split.
- now destruct r.
- intros r_eq.
destruct r; auto.
congruence.
Qed.
Lemma isOk_neq_isErr : forall {T E : Type} (r : result T E),
isOk r <> isErr r.
Proof.
intros.
destruct r; cbn; congruence.
Qed.
Inductive result T E :=
| Ok (t : T)
| Err (e : E).
Arguments Ok {_ _}.
Arguments Err {_ _}.
Global Instance Monad_result {E} : Monad (fun T => result T E) :=
{| ret _ t := Ok t;
bind _ _ mt f :=
match mt with
| Ok t => f t
| Err e => Err e
end |}.
Global Instance MonadLaws_Monad_result {E} : MonadLaws (@Monad_result E).
Proof.
constructor.
- auto.
- intros; cbn.
destruct t; auto.
- intros; cbn.
destruct t; auto.
Qed.
Definition result_of_option {T E : Type} (o : option T) (err : E) : result T E :=
match o with
| Some a => Ok a
| None => Err err
end.
Definition option_of_result {T E : Type} (r : result T E) : option T :=
match r with
| Ok t => Some t
| Err e => None
end.
Global Instance option_to_result
{E : Type}
: MonadTrans (fun T => E -> result T E) option :=
{| lift T (opt : option T) err := @result_of_option T E opt err |}.
Global Instance result_to_option
{E : Type}
: MonadTrans option (fun T => result T E) :=
{| lift T (opt : result T E) := @option_of_result T E opt |}.
Definition unpack_result {T E : Type} (r : result T E) :=
match r return match r with
| Ok _ => T
| Err _ => E
end with
| Ok t => t
| Err e => e
end.
Definition bind_error {T E1 E2 : Type} (f : E1 -> E2) (r : result T E1) : result T E2 :=
match r with
| Ok t => Ok t
| Err e => Err (f e)
end.
Definition isOk {T E : Type} (r : result T E) :=
match r with | Ok _ => true | Err _ => false end.
Definition isErr {T E : Type} (r : result T E) :=
match r with | Ok _ => false | Err _ => true end.
Lemma result_of_option_eq_some : forall {T E : Type} (x : option T) (e : E) (y : T),
result_of_option x e = Ok y <-> x = Some y.
Proof.
split; destruct x; intros eq;
(discriminate || injection eq as <-; reflexivity).
Qed.
Lemma result_of_option_eq_none : forall {T E : Type} (x : option T) (e1 e2 : E),
result_of_option x e1 = Err e2 -> x = None.
Proof.
destruct x;
(discriminate || reflexivity).
Qed.
Lemma isOk_Ok : forall {T E : Type} (r : result T E) (x : T),
r = Ok x -> isOk r = true.
Proof.
intros.
now subst.
Qed.
Lemma isOk_Err : forall {T E : Type} (r : result T E) (e : E),
r = Err e -> isOk r = false.
Proof.
intros.
now subst.
Qed.
Lemma isOk_exists : forall {T E : Type} (r : result T E),
isOk r = true <-> exists x : T, r = Ok x.
Proof.
split.
- intros.
destruct r; eauto.
discriminate.
- intros (x & r_eq).
eapply isOk_Ok.
eauto.
Qed.
Lemma isOk_not_exists : forall {T E : Type} (r : result T E),
isOk r = false <-> forall x : T, r <> Ok x.
Proof.
split.
- now destruct r.
- intros r_eq.
destruct r; auto.
congruence.
Qed.
Lemma isOk_neq_isErr : forall {T E : Type} (r : result T E),
isOk r <> isErr r.
Proof.
intros.
destruct r; cbn; congruence.
Qed.