Here's the code from a custom agda library. In the following code, π stands for vector and β for Natural numbers. The takeπ type is similar to that of Haskell. Example: "take 3 [1,2,3,4,5,6,7,8]" results in [1,2,3].
takeπ : β{A : Set}{n : β} β (m : β) β π A n β π A m
takeπ 0 xs = []
takeπ (suc m) (x :: xs) = x :: takeπ m xs
I keep getting the error:
Incomplete pattern matching for takeπ. Missing cases:
takeπ (suc m) [] when checking the definition of takeπ
I dont understand, what possible proof I might be missing out.
The type signature of takeπ says that for any completely unconstrained m you can return a Vec of length m having a Vec of length n. This is not true of course as m must be less or equal to n, because you want to return a prefix of a Vec. And since a number of elements to take and the length of a Vec are unrelated to each other, Agda gives you that error about incomplete pattern matching.
In Agda standard library the restriction that m is less or equal to the length of an input Vec is expressed as follows:
take : β {a} {A : Set a} m {n} β Vec A (m + n) β Vec A m
You can also define something like
take : β {a} {A : Set a} {m n} β m β€ n β Vec A n β Vec A m
Or even
take : β {a} {A : Set a} m {n} β Vec A n β Vec A (m β n)
to model the behavior of Data.List.take (where _β_ means min in Agda stdlib).
You are pattern-matching on m and a vector xs of type π A n. There is no guarantee that, because m is suc-headed that xs is non-empty. As the error suggests, you need to also consider the case where m is a suc and xs is empty.
Alternatively, you can write a function with a more precise type guaranteeing the fact that xs is at least as long as m. This is what is used in the standard library:
take : β {A : Set} m {n} β Vec A (m + n) β Vec A m
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With