如何编写接受长度小于 3 的 Vector 的 Idris 函数
How to write an Idris function that accepts a Vect of length less than 3
伊德里斯 1.2.0。我试图自动找到向量长度小于3的证明。
f : {n : Nat} -> {auto prf: n < 3 = True} -> Vect n a -> ()
f v = ()
f' : {n : Nat} -> {auto prf: isJust (natToFin n 3) = True} -> Vect n a -> ()
f' v = ()
这两个类型检查,并与 f {n=2} [1, 2}
甚至 f (the (Vect 2 Nat) [1, 2])
一起工作,但是当我像 f [1, 2]
这样称呼它时,我得到
When checking argument x to constructor Data.Vect.:::
No such variable len
我也试过另一种方法:
g : {x : Fin 3} -> Vect (finToNat x) a -> ()
g v = ()
这也适用于 g {x=2} [1, 2]
,但再次失败 g [1, 2]
When checking an application of function Main.g:
Type mismatch between
Vect 2 Integer (Type of [1, 2])
and
Vect (finToNat x) Integer (Expected type)
Specifically:
Type mismatch between
2
and
finToNat x
好吧,我想当 x
未知时,这两个表达式不会简化为相同的规范形式。
我不明白第一个错误。我怀疑它与 [] 语法重载有关。我做错了什么?
Idris 在尝试解决合一问题 finToNat x = 2
时不会尝试反转(单射)函数 finToNat
来猜测 x
的值。所以它只是卡住了。
在更一般的层面上,而不是在类型中推动计算或在隐式参数中进行证明搜索,我将通过以下任一方式表示有界向量:
record BoundedVec (n : Nat) (a : Type) where
size : Nat
less : LTE size n
vect : Vect size a
data BoundedVec : (n : Nat) -> (a : Type) -> Type where
Nil : BoundedVec n a
Cons : a -> BoundedVec n a -> BoundedVec (S n) a
感谢 gallais 提供的见解。这是一个完整的例子:
-- idris -p contrib
import Data.BoundedList
import Data.Vect
-- a function that takes a list of at most 3 elements
f : BoundedList 3 a -> ()
f xs = ()
-- a shorter vector
v : Vect 2 Int
v = [1, 2]
-- convert the vector to a bounded list and weaken the bound
bounded : BoundedList 3 Int
bounded = weaken $ fromList $ toList v
-- call the function
answer : ()
answer = f bounded
伊德里斯 1.2.0。我试图自动找到向量长度小于3的证明。
f : {n : Nat} -> {auto prf: n < 3 = True} -> Vect n a -> ()
f v = ()
f' : {n : Nat} -> {auto prf: isJust (natToFin n 3) = True} -> Vect n a -> ()
f' v = ()
这两个类型检查,并与 f {n=2} [1, 2}
甚至 f (the (Vect 2 Nat) [1, 2])
一起工作,但是当我像 f [1, 2]
这样称呼它时,我得到
When checking argument x to constructor Data.Vect.:::
No such variable len
我也试过另一种方法:
g : {x : Fin 3} -> Vect (finToNat x) a -> ()
g v = ()
这也适用于 g {x=2} [1, 2]
,但再次失败 g [1, 2]
When checking an application of function Main.g:
Type mismatch between
Vect 2 Integer (Type of [1, 2])
and
Vect (finToNat x) Integer (Expected type)
Specifically:
Type mismatch between
2
and
finToNat x
好吧,我想当 x
未知时,这两个表达式不会简化为相同的规范形式。
我不明白第一个错误。我怀疑它与 [] 语法重载有关。我做错了什么?
Idris 在尝试解决合一问题 finToNat x = 2
时不会尝试反转(单射)函数 finToNat
来猜测 x
的值。所以它只是卡住了。
在更一般的层面上,而不是在类型中推动计算或在隐式参数中进行证明搜索,我将通过以下任一方式表示有界向量:
record BoundedVec (n : Nat) (a : Type) where
size : Nat
less : LTE size n
vect : Vect size a
data BoundedVec : (n : Nat) -> (a : Type) -> Type where
Nil : BoundedVec n a
Cons : a -> BoundedVec n a -> BoundedVec (S n) a
感谢 gallais 提供的见解。这是一个完整的例子:
-- idris -p contrib
import Data.BoundedList
import Data.Vect
-- a function that takes a list of at most 3 elements
f : BoundedList 3 a -> ()
f xs = ()
-- a shorter vector
v : Vect 2 Int
v = [1, 2]
-- convert the vector to a bounded list and weaken the bound
bounded : BoundedList 3 Int
bounded = weaken $ fromList $ toList v
-- call the function
answer : ()
answer = f bounded