Coq基础(四) - 多态

多态

在前面所定义的链表中,链表的元素都是自然数,(或者PartitialMap中以一个二元元组为元素),但这些都存在着一个问题:所有类型的链表都在定义的都限制了链表的元素为某一个确定的类型,这样就不太灵活了,如果需要定义的链表类型比较多的话,那么就需要为每一种类型的链表单独写一段声明代码。

比如,需要一个布尔类型的链表:

Inductive boollist : Type :=
  | bool_nil
  | bool_cons (b : bool) (l : boollist).

 为了避免这样的重复,coq提供了一种称为多态的声明机制:

Inductive list (X:Type) : Type :=
  | nil
  | cons (x : X) (l : list X).

 Check list.
 (* ===> list : Type -> Type *)

 Check (nil nat).
 (* ===> nil nat : list nat *)

 Check (cons nat 3 (nil nat)).
 (* ===> cons nat 3 (nil nat) : list nat *)

 Check nil.
 (* ===> nil : forall X : Type, list X *)

 Check cons.
 (* ===> cons : forall X : Type, X -> list X -> list X *)

这种类型的声明语句需要在声明该类型的变量时多添建一个参数:元素的类型。

**隐式参数:**为了不必在每次使用多态链表时都添加一个类型参数,可以使用关键词[Arguements]来避免这种情况

[Arguments]关键词指定函数(或构造函数)的名称,然后列出它的实参名称,用花括号括住所有要视为隐式实参的实参:

Arguments nil {X}.
Arguments cons {X} _ _.

用同样的方法可以定义元组:

Inductive prod (X Y : Type) : Type :=
| pair (x : X) (y : Y).

Arguments pair {X} {Y} _ _.

Notation "( x , y )" := (pair x y).

以函数为参数的函数

和许多现代编程语言一样Coq允许函数作为参数传递给其他函数或者作为返回结果,如下:

Definition doit3times {X:Type} (f:X->X) (n:X) : X :=
  f (f (f n)).

  Example test_doit3times: doit3times minustwo 9 = 3.
  Proof. reflexivity. Qed.

将这类函数称为高阶函数,下面是一个比较有用的高阶函数,以一个链表以及布尔类型的函数作为参数,然后返回一个新的链表这个链表中的元素都能满足使那个布尔函数返回true,filter

Fixpoint evenb (n:nat) : bool :=
  match n with
  | O        => true
  | S O      => false
  | S (S n') => evenb n'
  end.

Fixpoint evenb (n:nat) : bool :=
  match n with
  | O        => true
  | S O      => false
  | S (S n') => evenb n'
  end.

Example test_filter1: filter evenb [1;2;3;4] = [2;4].
Proof. reflexivity.  Qed.

匿名函数:一般的函数在定义的时候都需要声明其函数名,然而在将函数作为参数传递给另一个函数的时候,可以使用匿名函数:

Example test_anon_fun':
  doit3times (fun n => n * n) 2 = 256.
Proof. reflexivity.  Qed.

此外,还有一个比较有用的高阶函数,同样的以一个函数以及一个链表作为参数,然后对链表中的每个元素都执行一次函数的操作,将函数的返回值插入一个新链表中,称为map:

Fixpoint map {X Y: Type} (f:X->Y) (l:list X) : (list Y) :=
  match l with
  | []     => []
  | h :: t => (f h) :: (map f t)
  end.

Example test_map1: map (fun x => plus 3 x) [2;0;2] = [5;3;5].
Proof. reflexivity.  Qed.
posted @ 2019-10-23 21:06  Hang3  阅读(450)  评论(0编辑  收藏  举报