Idris 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
未知时不会减少到相同的规范形式。
我不明白第一个错误。我怀疑它与[]语法重载有关。我做错了什么?
答案 0 :(得分:2)
在尝试解决统一问题finToNat
时,Idris不会尝试反转(内射)函数x
来猜测finToNat x = 2
的值。所以它只是卡住了。
在更一般的层面而不是在隐式参数的类型或证明搜索中推送计算,我将通过以下任一方式表示有界向量:
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
答案 1 :(得分:0)
感谢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