我正试图证明Monad法则(左右单位+相关性)为继续传球风格(CPS)Monad。
我正在使用https://coq.inria.fr/cocorico/AUGER_Monad中基于类型类的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).
CPS类型构造函数来自Ralf Hinze的Functional Pearl关于Haskell中的Compile-time parsing
Definition CPS (S:Type) := forall A, (S->A) -> A.
我定义了bind
和return_
这样的
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
|}.
但我仍然坚持right_unit
和associativity
的证明义务。
- unfold CPS; intros.
赋予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
非常感谢您的帮助!
编辑:AndrásKovács指出类型检查器中的eta转换已经足够,因此intros; apply eq_refl.
或reflexivity.
就足够了。
bind
的错误定义。 (隐形参数c
位于)
... 的错误一侧
Instance CPSMonad : Monad CPS :=
{|
return_ S s A f := f s ;
bind A B m k C c := m _ (fun a => k a _ c)
|}.
答案 0 :(得分:3)
正如comment András Kovács于3月11日12:26提到的解决方案
也许你可以尝试直接反思?从Coq 8.5开始,对记录进行了eta转换,因此所有定律都应该通过标准化和eta转换立即显现出来。
这给了我们以下实例:
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
|}.