Reputation: 298
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.
Upvotes: 3
Views: 238
Reputation: 12715
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).
Upvotes: 2
Reputation: 12093
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
Upvotes: 1