我正在阅读伊德里斯的书,我正在做第一次证明练习。
通过练习来证明same_lists
,我可以像这样实现它,匹配Refl
强制x
和y
来统一:
total same_lists : {xs : List a} -> {ys : List a} ->
x = y -> xs = ys -> x :: xs = y :: ys
same_lists Refl Refl = Refl
然而,当我试图以同样的方式证明其他东西时,我会遇到不匹配。例如:
total allSame2 : (x, y : Nat) -> x = y -> S x = S y
allSame2 x y Refl = Refl
编译器说:
Type mismatch between y = y (Type of Refl) and x = y (Expected type)
如果我在=
之后进行大小写匹配,无论是显式还是lambda,都可以按预期工作:
total allSame2 : (x : Nat) -> (y : Nat) -> x = y -> S x = S y
allSame2 x y = \Refl => Refl
这有什么区别?
另一个有效的修改是隐含有问题的参数:
total allSame2 : {x : Nat} -> {y : Nat} -> x = y -> S x = S y
allSame2 Refl = Refl
答案 0 :(得分:5)
我不知道所有细节,但我可以给你一个粗略的想法。在Idris中,命名函数的参数列表是特殊的,因为它是依赖模式匹配的一部分。模式匹配时,它还会重写其他参数。
same_lists x y Refl = Refl
无效,我粗略猜测,因为Idris重写x
和y
是相同的,并且不允许您为此单个值指定不同的名称 - 我希望有人可以更好地解释这个机制。相反,您可以使用same_lists x x Refl = Refl
- 并注意名称x
并不重要,只需在两个网站中使用相同的名称。
lambda参数与命名参数列表分开。因此,由于您在lambda中进行匹配,因此Idris仅在此时重写其他参数。关键是,在第一个例子中,Idris希望一次完成所有操作,因为它是相同参数列表的一部分。
最后一个例子是唯一的变化是你没有给参数赋予不同的名字。使用all_same _ _ Refl = Refl
也是有效的。当隐含参数时,Idris会为您正确填充它们。
最后,您可以考虑same_lists = \x, y, Refl => Refl
也可以。这是因为Idris不会在未命名的参数列表(即lambda参数)中重写。