定义列表函数的等式

时间:2016-05-06 01:53:18

标签: idris

Idris的类型驱动开发介绍了这个练习:

same_cons : {xs : List a} -> {ys : List a} -> xs = ys -> x :: xs = x :: ys

但是,我试图通过以下方式实现它:

data EqList : (xs : List a) -> (ys : List a) -> Type where
   Same : (xs: List a) -> EqList xs xs

sameS : (xs : List a) -> (ys : List a) -> (x: a) -> (eq : EqList xs ys) -> EqList (x :: xs) (x :: ys)
sameS xs xs x (Same xs) = Same (x :: xs)

same_cons : {xs : List a} -> {ys : List a} -> (eq : EqList xs ys) -> EqList (x :: xs) (x :: ys)
same_cons {xs} {ys} eq = sameS xs ys _ eq

我推断了x中的EqList (x :: xs) (x :: ys),因为如果xxs为空,我很难理解如何获得ys

此外,上面的编译,但当我试图调用它时失败了:

*Exercises> same_cons (Same [1,2,3])
(input):Can't infer argument x to same_cons

2 个答案:

答案 0 :(得分:2)

在您的用例中无法推断出隐式参数x,因为调用same_cons (Same [1,2,3])中没有信息可以将其约束为任何内容。如果您修改了结果的类型,那么您将可以选择x,例如

λΠ> the (EqList [0,1,2,3] [0,1,2,3]) (same_cons (Same [1,2,3]))
Same [0, 1, 2, 3] : EqList [0, 1, 2, 3] [0, 1, 2, 3]

因为[0,1,2,3]选择x:xsx0统一起来。

顺便说一下,您可以简化same_cons的定义,因为eq参数的类型决定了xsys,所以您可以让Idris推断它:

same_cons : (eq : EqList xs ys) -> EqList (x :: xs) (x :: ys)
same_cons eq = sameS _ _ _ eq

答案 1 :(得分:2)

澄清如何获得x: 如果它不是已经明确的,那么类型decleration中的小写字母将成为隐式参数。所以

same_cons : {xs : List a} -> {ys : List a} ->
            (eq : EqList xs ys) -> EqList (x :: xs) (x :: ys)

相同
same_cons : {a : Type} -> {x : a} -> {xs : List a} -> {ys : List a} -> 
            (eq : EqList xs ys) -> EqList (x :: xs) (x :: ys)

x隐藏的地方。因此,您可以使用定义左侧的{x}来获取它。或者只是让伊德里斯处理所有的东西并使用Cactus'定义。对于参数的未来问题,您可以在REPL中使用:set showimplicits在询问类型时显示所有隐式参数,例如: :t same_cons

当Idris无法推断隐式参数的值时,您可以通过给出类似Cactus的结果类型来帮助它,或者将隐式参数设置为值:

*> same_cons {x=0} (Same [3,2,5])
Same [0, 3, 2, 5] : EqList [0, 3, 2, 5] [0, 3, 2, 5]