Define Equality of Lists Function

人走茶凉 提交于 2019-12-12 04:07:29

问题


Type-Driven Development with Idris presents this exercise:

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

However, I attempted to implement it via:

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

I inferred the x in EqList (x :: xs) (x :: ys) because I'm confused how to get an x if xs and ys are empty.

Also, the above compiles, but it failed when I tried to call it:

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

回答1:


The implicit argument x cannot be inferred in your use case because there is no information in the call same_cons (Same [1,2,3]) to constrain it to anything. If you fix the type of the result, that will give you the choice of x, e.g.

λΠ> 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]

since the choice of [0,1,2,3] for x:xs unifies x with 0.

BTW you can simplify the definition of same_cons since the eq argument's type determines xs and ys so you can let Idris infer it:

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



回答2:


To clarify on how to get the x: Everything in lowercase in the type decleration will become an implicit argument, if it isn't already explicit. So

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

is the same as

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

That's where the x is hiding. So you could use {x} on the left hand side of the definition to get it. Or just let Idris handle all the stuff and use Cactus' definition. For future problems with arguments, you can use :set showimplicits in the REPL to show you all the implicit arguments when asking for types, e.g. :t same_cons.

And when Idris cannot infer the value for an implicit argument, you can help it by giving the resulting type like Cactus did or set the implicit argument to a value:

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


来源:https://stackoverflow.com/questions/37063005/define-equality-of-lists-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!