In this answer on a question about the totality checker wurde eine Problemumgehung mit case
anstelle von with
empfohlen.`case`, das Argumente verfeinert
In Situationen jedoch, in denen das Ergebnis der Übereinstimmung den Typ der anderen Argumente verfeinert, ist diese Umwandlung nicht einfach zu machen.
beispielsweise angesichts der folgenden Definitionen:
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))
folgende Definition typechecks, ist aber nicht als insgesamt akzeptiert:
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))
während die folgenden man nicht typecheck:
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))
aufgrund
Type mismatch between
IsEven (k + k) k (Type of Times2 k)
and
IsEven n k (Expected type)
Ich habe auch versucht 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)
aber hier wird foo1'
auch nicht als insgesamt akzeptiert:
foo1' is not total as there are missing cases
Wow! Bitte schau dir 'foo2' hier an: https://pastebin.com/KbS6vT0H :) –