Since the _+_
-Operation for Nat
is usually defined recursively in the first argument, its obviously non-trivial for the type-checker to know that i + 0 == i
. However, I frequently run into this issue when I write functions on fixed-size Vectors.
One example: How can I define an Agda-function
swap : {A : Set}{m n : Nat} -> Vec A (n + m) -> Vec A (m + n)
which puts the first n
values at the end of the vector?
Since a simple solution in Haskell would be
swap 0 xs = xs
swap n (x:xs) = swap (n-1) (xs ++ [x])
I tried it analogously in Agda like this:
swap : {A : Set}{m n : Nat} -> Vec A (n + m) -> Vec A (m + n)
swap {_} {_} {zero} xs = xs
swap {_} {_} {suc i} (x :: xs) = swap {_} {_} {i} (xs ++ (x :: []))
But the type checker fails with the message (which relates to the the {zero}
-case in the above swap
-Definition):
.m != .m + zero of type Nat
when checking that the expression xs has type Vec .A (.m + zero)
So, my question: How to teach Agda, that m == m + zero
? And how to write such a swap
Function in Agda?
n
) implicit in your signature ofswap
, since Agda won't be able to infer it. – copumpkinswap
is used)? – phynfoVec Nat (5 + 3)
. That addition will reduce the type immediately toVec Nat 8
, which Agda will then try to unify withVec A (n + m)
and will then throw its hands up in the air (i.e., make your term yellow) because it can't magically do subtraction. I'm reasonably sure that even with Agda's fancy Miller pattern unification, there won't be any cases where it can infern
andm
from context. – copumpkin