Coq let子句中的多个赋值

时间:2016-10-26 07:00:57

标签: syntax-error coq let

我是Coq的新手,只是想弄清楚基本的语法。如何向let添加多个子句?这是我想写的功能:

Definition split {A:Set} (lst:list A) :=
  let
    fst := take (length lst / 2) lst
    snd := drop (length lst / 2) lst
  in (fst, snd) end.

这是错误:

  

语法错误:在[constr:operconstr level 200]之后预期的'in'(在[constr:binder_constr]中)。

我认为在in定义后需要fst

1 个答案:

答案 0 :(得分:4)

确实,在第一个标识符后需要in。根据参考手册(§1.2.12):

  

let ident := term1 in term2表示term1ident中变量term2的本地绑定。

您需要多个(嵌套)let ... in表达式:

Definition split {A:Set} (lst:list A) :=
  let fst := take (length lst / 2) lst in
  let snd := drop (length lst / 2) lst in
    (fst, snd).

顺便说一句,您可以使用标准库中的firstnskipn函数(List module)而不是takedrop

Require Import Coq.Lists.List.
Import ListNotations.
Compute firstn 3 [1;2;3;4;5].    (* Result: [1;2;3] *)
Compute skipn 3 [1;2;3;4;5].     (* Result: [4;5]   *)

这(以及一点点重构)导致split的以下定义(我重命名它以避免split标准函数的阴影):

Definition split_in_half {A:Set} (lst:list A) :=
  let l2 := Nat.div2 (length lst) in
    (firstn l2 lst, skipn l2 lst).

Compute split_in_half [1;2;3;4;5].    (* Result: ([1; 2], [3; 4; 5])  *)

顺便提一下,如果你担心输入列表上的多次传递,它仍然有很大的改进空间。如果您打算进行提取,例如,您可以进入OCaml。