为什么这个 'with' 块破坏了这个函数的整体性?
Why does this 'with' block spoil the totality of this function?
我正在尝试通过自然数计算奇偶校验和下半场:
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
parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n))
我尝试使用 parity
的明显实现:
parity Z = Left $ Evidence _ $ Times2 0
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0
parity (S (S n)) with (parity n)
parity (S (S (k + k))) | Left (Evidence _ (Times2 k)) =
Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k)
parity (S (S (S ((k + k))))) | Right (Evidence _ (Times2Plus1 k)) =
Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k)
这会按预期进行类型检查和工作。但是,如果我尝试将 parity
标记为 total
,Idris 开始抱怨:
parity is possibly not total due to: with block in parity
我在 parity
中看到的唯一 with
块是从 parity (S (S n))
到 parity n
的递归调用,但显然这是有根据的,因为n
在结构上小于 S (S n)
。
如何让 Idris 相信 parity
是完整的?
对我来说这看起来像是一个错误,因为以下基于 case
的解决方案通过了完整性检查器:
total
parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n))
parity Z = Left $ Evidence _ $ Times2 0
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0
parity (S (S k)) =
case (parity k) of
Left (Evidence k (Times2 k)) =>
Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k)
Right (Evidence k (Times2Plus1 k)) =>
Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k)
我正在尝试通过自然数计算奇偶校验和下半场:
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
parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n))
我尝试使用 parity
的明显实现:
parity Z = Left $ Evidence _ $ Times2 0
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0
parity (S (S n)) with (parity n)
parity (S (S (k + k))) | Left (Evidence _ (Times2 k)) =
Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k)
parity (S (S (S ((k + k))))) | Right (Evidence _ (Times2Plus1 k)) =
Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k)
这会按预期进行类型检查和工作。但是,如果我尝试将 parity
标记为 total
,Idris 开始抱怨:
parity is possibly not total due to: with block in parity
我在 parity
中看到的唯一 with
块是从 parity (S (S n))
到 parity n
的递归调用,但显然这是有根据的,因为n
在结构上小于 S (S n)
。
如何让 Idris 相信 parity
是完整的?
对我来说这看起来像是一个错误,因为以下基于 case
的解决方案通过了完整性检查器:
total
parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n))
parity Z = Left $ Evidence _ $ Times2 0
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0
parity (S (S k)) =
case (parity k) of
Left (Evidence k (Times2 k)) =>
Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k)
Right (Evidence k (Times2Plus1 k)) =>
Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k)