Сначала 1 + n
легче рассуждать о проверке типов, чем n + 1
, поскольку шаблон plus
соответствует левой стороне:
> :printdef plus
plus : Nat -> Nat -> Nat
plus 0 right = right
plus (S left) right = S (plus left right)
Так что n + 1
в определении типа не может быть уменьшается без знания n
, в то время как 1 + n
может быть уменьшено до S n
.
С этим одним компилируется fibs
. Но если вы хотите проверить, является ли функция итоговой, вы получите:
> :total fibs
Main.fibs is possibly not total due to:
Main.case block in fibs at test.idr:7:10-17, which is not total as there are missing cases
Поскольку средство проверки типов не просматривает другие предложения, оно не знает, что fibs (S Z)
уже обрабатывается в другом месте. Таким образом, в fibs (S k) = case (fibs k) of …
k
может быть Z
, а затем результат Vect (S Z)
, который не обрабатывается в переключателе регистра.
Но исправление так же просто, как первый, просто сопоставление с образцом на S (S k)
:
fibs (S (S k)) = case (fibs (S k)) of
(x :: y :: xs) => (x + y) :: x :: y :: xs