3

I'm trying to prove the Monad laws (left and right unit + associativity) for the Continuation Passing Style (CPS) Monad.

I'm using a Type Class based Monad defintion from https://coq.inria.fr/cocorico/AUGER_Monad:

Class Monad (m: Type -> Type): Type :=
  {
    return_ {A}:     A -> m A;
    bind    {A B}:   m A -> (A -> m B) -> m B;

    right_unit {A}:  forall (a: m A), bind a return_ = a;
    left_unit  {A}:  forall (a: A) B (f: A -> m B),
                       bind (return_ a) f = f a;
    associativity {A B C}:
                     forall a (f: A -> m B) (g: B -> m C),
                       bind a (fun x => bind (f x) g) = bind (bind a f) g
}.

Notation "a >>= f" := (bind a f) (at level 50, left associativity).

The CPS type constructor is from Ralf Hinze's Functional Pearl about Compile-time parsing in Haskell

Definition CPS (S:Type) := forall A, (S->A) -> A.

I defined bind and return_ like this

Instance CPSMonad : Monad CPS  :=
  {|
    return_ := fun {A} a {B} => fun (f:A->B) => f a ;
    bind A B := fun (m:CPS A) (k: A -> CPS B)
      =>(fun C => (m _ (fun a => k a _))) : CPS B

  |}.

but I'm stuck with the proof obligations for right_unit and associativity.

- unfold CPS; intros.

gives the obligation for right_unit:

  A : Type
  a : forall A0 : Type, (A -> A0) -> A0
  ============================
   (fun C : Type => a ((A -> C) -> C) (fun (a0 : A) (f : A -> C) => f a0)) = a

Would be very grateful for help!

EDIT: András Kovács pointed out that eta conversion in the type checker is sufficient, so intros; apply eq_refl., or reflexivity. is enough.

Bur first I had to correct my incorrect definition of bind. (The invisible argument c was on the wrong side of the )...

Instance CPSMonad : Monad CPS  :=
  {|
    return_ S s A f     := f s ;
    bind    A B m k C c := m _ (fun a => k a _ c)
  |}.
Olivier Verdier
  • 46,998
  • 29
  • 98
  • 90
larsr
  • 5,447
  • 19
  • 38
  • 3
    Maybe you could try going straight for `reflexivity`? From Coq 8.5 there's eta conversion for records, so all the laws should be apparent immediately by normalization and eta conversion. – András Kovács Mar 11 '16 at 12:26
  • Thanks! You are absolutely correct. It also works in 8.4. – larsr Mar 11 '16 at 12:52
  • @larsr Want to answer your own question and accept it so this isn't marked "unanswered"? – Langston Nov 14 '16 at 06:34

1 Answers1

3

The solution, as mentioned in a comment by András Kovács on Mar 11 at 12:26, is

Maybe you could try going straight for reflexivity? From Coq 8.5 there's eta conversion for records, so all the laws should be apparent immediately by normalization and eta conversion.

That gives us the following instance:

Instance CPSMonad : Monad CPS  :=
  {|
    return_       S s A f :=     f s ;
    bind          A B m k C c := m _ (fun a => k a _ c) ;
    right_unit    A a :=         eq_refl ;
    left_unit     A a B f :=     eq_refl ;
    associativity A B C a f g := eq_refl
  |}.
Community
  • 1
  • 1
larsr
  • 5,447
  • 19
  • 38