ExtLib.Structures.MonadLaws
Require Import Setoid.
Require Import Coq.Classes.Morphisms.
Require Import ExtLib.Structures.Monads.
Require Import ExtLib.Data.Fun.
Require Import ExtLib.Data.Unit.
Set Implicit Arguments.
Set Strict Implicit.
Section MonadLaws.
Variable m : Type -> Type.
Variable M : Monad m.
Require Import Coq.Classes.Morphisms.
Require Import ExtLib.Structures.Monads.
Require Import ExtLib.Data.Fun.
Require Import ExtLib.Data.Unit.
Set Implicit Arguments.
Set Strict Implicit.
Section MonadLaws.
Variable m : Type -> Type.
Variable M : Monad m.
This <= relation is a computational <= relation based on the ideas
of domain theory. It generalizes the usual equivalence relation by,
enabling the relation to talk about computations that are "more defined"
than others.
**This generalization is done to support the fixpoint law.
Class MonadLaws :=
{ bind_of_return : forall {A B} (a : A) (f : A -> m B),
bind (ret a) f = f a
; bind_associativity :
forall {A B C} (aM:m A) (f:A -> m B) (g:B -> m C),
bind (bind aM f) g = bind aM (fun a => bind (f a) g)
}.
Class MonadTLaws {n} (nM : Monad n) (MT : MonadT m n) :=
{ lift_ret : forall {T} (x : T),
lift (ret x) = ret x
; lift_bind : forall {T U} (c : n T) (f : T -> n U),
lift (bind c f) = bind (lift c) (fun x => lift (f x))
}.
Section with_state.
Context {S : Type}.
Class MonadStateLaws (MS : MonadState S m) : Type :=
{ get_put : bind get put = ret tt
; put_get : forall x : S,
bind (put x) (fun _ => get) = bind (put x) (fun _ => ret x)
; put_put : forall {A} (x y : S) (f : unit -> m A),
bind (put x) (fun _ => bind (put y) f) = bind (put y) f
; get_get : forall {A} (f : S -> S -> m A),
bind get (fun s => bind get (f s)) = bind get (fun s => f s s)
; get_ignore : forall {A} (aM : m A),
bind get (fun _ => aM) = aM
}.
Class MonadReaderLaws (MR : MonadReader S m) : Type :=
{ ask_local : forall f : S -> S,
local f ask = bind ask (fun x => ret (f x))
; local_bind : forall {A B} (aM : m A) (f : S -> S) (g : A -> m B),
local f (bind aM g) = bind (local f aM) (fun x => local f (g x))
; local_ret : forall {A} (x : A) (f : S -> S),
local f (ret x) = ret x
; local_local : forall {T} (s s' : S -> S) (c : m T),
local s (local s' c) = local (fun x => s' (s x)) c
}.
End with_state.
Class MonadZeroLaws (MZ : MonadZero m) : Type :=
{ bind_zero : forall {A B} (f : A -> m B),
bind mzero f = mzero
}.
Class MonadFixLaws (MF : MonadFix m) : Type :=
{ mleq : forall {T}, relation T -> relation (m T)
; mfix_monotonic : forall {T U} (F : (T -> m U) -> T -> m U),
respectful eq (mleq eq) (mfix F) (F (mfix F))
}.
End MonadLaws.