Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
102 lines (73 sloc)
3.01 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Require Import ExtLib.Structures.Functor. | |
| Require Import ExtLib.Structures.Applicative. | |
| Set Implicit Arguments. | |
| Set Strict Implicit. | |
| Set Universe Polymorphism. | |
| Class Monad@{d c} (m : Type@{d} -> Type@{c}) : Type := | |
| { ret : forall {t : Type@{d}}, t -> m t | |
| ; bind : forall {t u : Type@{d}}, m t -> (t -> m u) -> m u | |
| }. | |
| Section monadic. | |
| Definition liftM@{d c} | |
| {m : Type@{d} -> Type@{c}} | |
| {M : Monad m} | |
| {T U : Type@{d}} (f : T -> U) : m T -> m U := | |
| fun x => bind x (fun x => ret (f x)). | |
| Definition liftM2@{d c} | |
| {m : Type@{d} -> Type@{c}} | |
| {M : Monad m} | |
| {T U V : Type@{d}} (f : T -> U -> V) : m T -> m U -> m V := | |
| Eval cbv beta iota zeta delta [ liftM ] in | |
| fun x y => bind x (fun x => liftM (f x) y). | |
| Definition liftM3@{d c} | |
| {m : Type@{d} -> Type@{c}} | |
| {M : Monad m} | |
| {T U V W : Type@{d}} (f : T -> U -> V -> W) : m T -> m U -> m V -> m W := | |
| Eval cbv beta iota zeta delta [ liftM2 ] in | |
| fun x y z => bind x (fun x => liftM2 (f x) y z). | |
| Definition apM@{d c} | |
| {m : Type@{d} -> Type@{c}} | |
| {M : Monad m} | |
| {A B : Type@{d}} (fM:m (A -> B)) (aM:m A) : m B := | |
| bind fM (fun f => liftM f aM). | |
| (* Left-to-right composition of Kleisli arrows. *) | |
| Definition mcompose@{c d} | |
| {m:Type@{d}->Type@{c}} | |
| {M: Monad m} | |
| {T U V:Type@{d}} | |
| (f: T -> m U) (g: U -> m V): (T -> m V) := | |
| fun x => bind (f x) g. | |
| Definition join@{d c} {m : Type@{d} -> Type@{c}} {a} `{Monad m} : m (m a) -> m a := | |
| fun x => bind x (fun y => y). | |
| End monadic. | |
| Module MonadBaseNotation. | |
| Delimit Scope monad_scope with monad. | |
| Notation "c >>= f" := (@bind _ _ _ _ c f) (at level 58, left associativity) : monad_scope. | |
| Notation "f =<< c" := (@bind _ _ _ _ c f) (at level 61, right associativity) : monad_scope. | |
| Notation "f >=> g" := (@mcompose _ _ _ _ _ f g) (at level 61, right associativity) : monad_scope. | |
| Notation "e1 ;; e2" := (@bind _ _ _ _ e1%monad (fun _ => e2%monad))%monad | |
| (at level 61, right associativity) : monad_scope. | |
| End MonadBaseNotation. | |
| Module MonadNotation. | |
| Export MonadBaseNotation. | |
| Notation "x <- c1 ;; c2" := (@bind _ _ _ _ c1 (fun x => c2)) | |
| (at level 61, c1 at next level, right associativity) : monad_scope. | |
| Notation "' pat <- c1 ;; c2" := | |
| (@bind _ _ _ _ c1 (fun x => match x with pat => c2 end)) | |
| (at level 61, pat pattern, c1 at next level, right associativity) : monad_scope. | |
| End MonadNotation. | |
| Module MonadLetNotation. | |
| Export MonadBaseNotation. | |
| Notation "'let*' p ':=' c1 'in' c2" := (@bind _ _ _ _ c1 (fun p => c2)) | |
| (at level 61, p as pattern, c1 at next level, right associativity) : monad_scope. | |
| End MonadLetNotation. | |
| Section Instances. | |
| Universe d c. | |
| Context (m : Type@{d} -> Type@{c}) {M : Monad m}. | |
| Global Instance Functor_Monad@{} : Functor m := | |
| { fmap := @liftM _ _ }. | |
| Global Instance Applicative_Monad@{} : Applicative m := | |
| { pure := @ret _ _ | |
| ; ap := @apM _ _ | |
| }. | |
| End Instances. |