Idris can't unify n
with n + m
because it does not know that n = n + 0
. You need to help him by manually proving that.
First of all, why it needs this proof. The reason is that take
expects Vect (n+m) a
:
Idris> :t Vect.take
Prelude.Vect.take : (n : Nat) -> Vect (n + m) a -> Vect n a
So, this will typecheck
foo: Vect (n + 0) String -> Vect n String
foo {n} xs = take n xs
You need a way to convert Vect n a
to Vect (n + 0) a
:
addNothing : {n : Nat} -> {a : Type} -> Vect n a -> Vect (n+Z) a
It is possible with replace
function:
Idris> :t replace
replace : (x = y) -> P x -> P y
But now you need a proof that n = n + 0
. Here it is (with the rest of the code):
plusAddZero : (n : Nat) -> n = n + 0
plusAddZero = proof
intros
rewrite (plusCommutative n 0)
trivial
addNothing : {n : Nat} -> {a : Type} -> Vect n a -> Vect (n + 0) a
addNothing {n} {a} = replace {P = \m => Vect m a} (plusAddZero n)
foo : Vect n String -> Vect n String
foo {n} xs = Vect.take n (addNothing xs)
Seems like too much for such a simple function. Hope someone will show more concise solution.
m
is defined ? – Guillaume Massém
is a type variable fromVector.take
– max taldykintake
was intended for, since it's always going to result inxs
. Or is this part of something larger? I have a more concise solution anyway, which I'll give as a proper answer rather than a comment. – Edwin Brady