我试图实现一个只计算一个包中某些nat出现次数的函数(只是列表的同义词)。
这就是我想要做的,但它不起作用:
Require Import Coq.Lists.List.
Import ListNotations.
Definition bag := list nat.
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => O
| v :: t => S (count v t)
| _ :: t => count v t
end.
Coq说最后一个条款是多余的,即它只是将v
视为头部的名称,而不是传递给计数调用的特定v
。有没有办法模式匹配作为函数参数传递的值?如果没有,我应该如何编写函数?
我让这个工作:
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => O
| h :: t => if (beq_nat v h) then S (count v t) else count v t
end.
但我不喜欢它。如果可能,我宁愿模式匹配。
答案 0 :(得分:3)
模式匹配是一种与平等不同的结构,旨在区分以“归纳”形式编码的数据,作为函数式编程的标准。
特别是,在许多情况下,模式匹配不足,例如当您需要潜在的无限模式时。
话虽这么说,一个更合理的计数类型是math-comp库中可用的类型:
count : forall T : Type, pred T -> seq T -> nat
Fixpoint count s := if s is x :: s' then a x + count s' else 0.
然后,您可以将您的函数构建为count (pred1 x)
,其中pred1 : forall T : eqType, T -> pred T
,也就是说,具有可判定(可计算)相等的类型的固定元素的一元等式谓词; pred1 x y <-> x = y
。
答案 1 :(得分:0)
我在另一个练习中发现,可以在函数的输出上打开match子句。在这种情况下,它是“基础”中的“ evenb”。在这种情况下,请尝试“ eqb”。
答案 2 :(得分:0)
好吧,由于v
在比赛中不起作用,我想也许我可以问一下列表的开头是否等于v
。是的,它奏效了。这是代码:
Fixpoint count (v : nat) (s : bag) : nat :=
match s with
| nil => 0
| x :: t =>
match x =? v with
| true => S ( count v t )
| false => count v t
end
end.