Dans this answer on a question about the totality checker, une solution de contournement impliquant l'utilisation de case
au lieu de with
a été recommandée. Cependant, dans les situations où le résultat de la correspondance affine le type d'autres arguments, cette transformation n'est pas simple à faire.`case` qui affine les arguments
Par exemple, étant donné les définitions suivantes:
data IsEven : Nat -> Nat -> Type where
Times2 : (n : Nat) -> IsEven (n + n) n
data IsOdd : Nat -> Nat -> Type where
Times2Plus1 : (n : Nat) -> IsOdd (S (n + n)) n
total parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n))
les typable définition suivants, mais ne sont pas acceptés comme total:
foo1 : Nat -> Nat
foo1 n with (parity n)
foo1 [email protected](k + k) | Left (Evidence _ (Times2 k)) = (n * n)
foo1 [email protected](S (k + k)) | Right (Evidence _ (Times2Plus1 k)) = (2 * (k * n + k))
alors que le suivant ne Typecheck pas:
foo2 : Nat -> Nat
foo2 n = case parity n of
Left (Evidence k (Times2 k)) => n * n
Right (Evidence k (Times2Plus1 k)) => (2 * (k * n + k))
en raison de
Type mismatch between
IsEven (k + k) k (Type of Times2 k)
and
IsEven n k (Expected type)
J'ai aussi essayé expanding the with
in foo1
:
foo1' : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n)) -> Nat
foo1' [email protected](k + k) (Left (Evidence k (Times2 k))) = (n * n)
foo1' [email protected](S (k + k)) (Right (Evidence k (Times2Plus1 k))) = 2 * (k * n + k)
foo1 : Nat -> Nat
foo1 n = foo1' n (parity n)
mais ici, foo1'
est pas non plus accepté comme total:
foo1' is not total as there are missing cases
Wow! S'il vous plaît regardez 'foo2' ici: https://pastebin.com/KbS6vT0H :) –