为什么Idris的Refl有时候不会打字?

时间:2017-04-28 12:22:29

标签: idris

我正在阅读伊德里斯的书,我正在做第一次证明练习。

通过练习来证明same_lists,我可以像这样实现它,匹配Refl强制xy来统一:

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

1 个答案:

答案 0 :(得分:5)

我不知道所有细节,但我可以给你一个粗略的想法。在Idris中,命名函数的参数列表是特殊的,因为它是依赖模式匹配的一部分。模式匹配时,它还会重写其他参数。

same_lists x y Refl = Refl无效,我粗略猜测,因为Idris重写xy是相同的,并且不允许您为此单个值指定不同的名称 - 我希望有人可以更好地解释这个机制。相反,您可以使用same_lists x x Refl = Refl - 并注意名称x并不重要,只需在两个网站中使用相同的名称。

lambda参数与命名参数列表分开。因此,由于您在lambda中进行匹配,因此Idris仅在此时重写其他参数。关键是,在第一个例子中,Idris希望一次完成所有操作,因为它是相同参数列表的一部分。

最后一个例子是唯一的变化是你没有给参数赋予不同的名字。使用all_same _ _ Refl = Refl也是有效的。当隐含参数时,Idris会为您正确填充它们。

最后,您可以考虑same_lists = \x, y, Refl => Refl也可以。这是因为Idris不会在未命名的参数列表(即lambda参数)中重写。

相关问题