Library Prelude.Control.Option
From Prelude Require Import Init Control Equality.
#[local]
Open Scope prelude_scope.
Bind Scope monad_scope with option.
Inductive is_some {a}: option a -> Prop :=
| is_some_rule (x: a): is_some (Some x).
#[program]
Definition is_some_dec {a} (x : option a) : { is_some x } + { ~ is_some x } :=
match x with
| Some x => left (is_some_rule x)
| None => right _
end.
Next Obligation.
now intro H.
Defined.
Definition maybe {a b} (f : a -> b) (x : b) (o : option a) : b :=
match o with
| Some o => f o
| None => x
end.
Definition fromMaybe {a} (x : a) (o : option a) : a :=
maybe id x o.
#[program]
Instance option_Functor : Functor option :=
{ map := option_map
}.
Next Obligation.
destruct x.
+ now constructor.
+ constructor.
Defined.
Next Obligation.
destruct x.
+ now constructor.
+ constructor.
Defined.
Definition option_app {a b} (f : option (a -> b)) (x : option a) : option b :=
match f with
| Some f => f <$> x
| None => None
end.
#[program]
Instance option_Applicative : Applicative option :=
{ apply := @option_app
; pure := @Some
}.
Next Obligation.
destruct v; now constructor.
Defined.
Next Obligation.
destruct w; destruct v; destruct u; now constructor.
Defined.
Next Obligation.
now constructor.
Defined.
Next Obligation.
destruct u; now constructor.
Defined.
Next Obligation.
destruct x; now constructor.
Defined.
Definition option_bind {a b} (x : option a) (f : a -> option b) : option b :=
match x with
| Some x => f x
| None => None
end.
#[program]
Instance option_Monad
: Monad option :=
{ bind := @option_bind
}.
Next Obligation.
destruct (f x); now constructor.
Defined.
Next Obligation.
destruct x; now constructor.
Defined.
Next Obligation.
destruct f; cbn; [| constructor ].
destruct (g a0); cbn; [| constructor ].
destruct (h b0); now constructor.
Defined.
Next Obligation.
destruct x; [| constructor].
apply H0.
Defined.
Next Obligation.
destruct x; now constructor.
Defined.