Why? Because the type system in Coq is so powerful we hardly even need them. In fact with a bit of syntactic sugar for inductively defined types and the generation of constructors we magically get something like first class modules (first-class meaning modules that are actually values that can be passed around to functions etc...). Enter the Record.

Record MonadBind : Type := { M : forall (A : Type), Type; bind : forall (A B : Type), M A -> (A -> M B) -> M B; ret : forall (A : Type), A -> M A; left_unit : forall (A B : Type) (f : A -> M B) (a : A), bind A B (ret A a) f = f a; right_unit : forall (A B : Type) (m : M A), bind A A m (ret A) = m; bind_assoc : forall (A B C : Type) (m : M A) (f : A -> M B) (g : B -> M C) (x : B), bind B C (bind A B m f) g = bind A C m (fun x => bind B C (f x) g) }.

This implements exactly the same strict controls on the instantiation of a Monad that were given with our MONAD signature in the previous post. Each type can rely on previously defined types in the record giving us the full dependent type system needed to specify a proper monad. With a little bit of work we can rewrite our module to be an instantiation of a record.

Look here for the example code

How cool is that!

## No comments:

## Post a Comment