Idris "did not change type" 用于用完全相同的类型重写
Idris "did not change type" for rewrite with exact same type
Context 我正在尝试为 Vect
编写 ++
的版本,其中编译器可以推断出结果 Vect
具有预期内容。
详细信息我正在努力了解为什么第二次重写不起作用
import Data.Vect
import Data.Nat
infixl 9 ++:
public export
(++:) : {0 r, r' : Nat} -> Vect r Nat -> Vect r' Nat -> Vect (r' + r) Nat
(++:) [] y = rewrite plusZeroRightNeutral r' in y
(++:) {r = S rr} (x :: xs) y = rewrite plusSuccRightSucc r' rr in x :: (xs ++: y)
我特意在签名中以相反的顺序添加了矢量长度,以使 API 更易于使用。我看到了
"tmp.idr" 8L, 254C written
Error: While processing right hand side of ++:. Rewriting by S (r' + rr) = r' + S rr did not change type Vect (r' + S rr) Nat.
/src/tmp.idr:8:32--8:82
|
8 | (++:) {r = S rr} (x :: xs) y = rewrite plusSuccRightSucc r' rr in x :: (xs ++: y)
我不明白为什么 r' + S rr
等于 S (r' + rr)
的证明不重写 r' + S rr
。这是我没有 rewrite
时的错误
"tmp.idr" 8L, 219C written
Error: While processing right hand side of ++:. Can't solve constraint between: S (plus r' rr) and plus r' (S rr).
/src/tmp.idr:8:32--8:47
|
8 | (++:) {r = S rr} (x :: xs) y = x :: (xs ++: y)
| ^^^^^^^^^^^^^^^
这很简单,因为 rewrite
以相反的顺序工作。所以如果目标是 goal
但你有 a
,你需要证明 goal = a
,而不是 a = goal
。 (我发现这总是很混乱,因为背景中的 replace
需要 a = goal
,但我猜这是因为 rewrite
重写了目标项。)因此 sym
这个应该工作:
(++:) {r = S rr} (x :: xs) y = rewrite sym $ plusSuccRightSucc r' rr in x :: (xs ++: y)
Context 我正在尝试为 Vect
编写 ++
的版本,其中编译器可以推断出结果 Vect
具有预期内容。
详细信息我正在努力了解为什么第二次重写不起作用
import Data.Vect
import Data.Nat
infixl 9 ++:
public export
(++:) : {0 r, r' : Nat} -> Vect r Nat -> Vect r' Nat -> Vect (r' + r) Nat
(++:) [] y = rewrite plusZeroRightNeutral r' in y
(++:) {r = S rr} (x :: xs) y = rewrite plusSuccRightSucc r' rr in x :: (xs ++: y)
我特意在签名中以相反的顺序添加了矢量长度,以使 API 更易于使用。我看到了
"tmp.idr" 8L, 254C written
Error: While processing right hand side of ++:. Rewriting by S (r' + rr) = r' + S rr did not change type Vect (r' + S rr) Nat.
/src/tmp.idr:8:32--8:82
|
8 | (++:) {r = S rr} (x :: xs) y = rewrite plusSuccRightSucc r' rr in x :: (xs ++: y)
我不明白为什么 r' + S rr
等于 S (r' + rr)
的证明不重写 r' + S rr
。这是我没有 rewrite
"tmp.idr" 8L, 219C written
Error: While processing right hand side of ++:. Can't solve constraint between: S (plus r' rr) and plus r' (S rr).
/src/tmp.idr:8:32--8:47
|
8 | (++:) {r = S rr} (x :: xs) y = x :: (xs ++: y)
| ^^^^^^^^^^^^^^^
这很简单,因为 rewrite
以相反的顺序工作。所以如果目标是 goal
但你有 a
,你需要证明 goal = a
,而不是 a = goal
。 (我发现这总是很混乱,因为背景中的 replace
需要 a = goal
,但我猜这是因为 rewrite
重写了目标项。)因此 sym
这个应该工作:
(++:) {r = S rr} (x :: xs) y = rewrite sym $ plusSuccRightSucc r' rr in x :: (xs ++: y)