我是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
?
答案 0 :(得分:4)
确实,在第一个标识符后需要in
。根据参考手册(§1.2.12):
let ident := term1 in term2
表示term1
与ident
中变量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).
顺便说一句,您可以使用标准库中的firstn
和skipn
函数(List
module)而不是take
和drop
:
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。