以下是教程中的示例,为简单起见略作修改:
data Vect : Nat -> (b:Type) -> Type where
Nil : Vect Z a
(::) : a -> Vect k a -> Vect (S k) a
data Elem : a -> Vect n a -> Type where
Here : {x:a} -> {xs:Vect n a} -> Elem x (x :: xs)
There : {x,y:a} -> {xs:Vect n a} -> Elem x xs -> Elem x (y :: xs)
testVec : Vect 4 Int
testVec = 3 :: 4 :: 5 :: 6 :: Nil
inVect : Elem 4 testVec
inVect = There Here
我无法理解There
如何验证值是否正确。
据我所知,There
就像一个函数,所以它需要
类型为Here
的元素,在填充孔时对应Elem 3 testVec
,然后将testVec
的第一个值设置为y
,其余值设置为xs
}。但是,因为y
没有在任何地方使用,我会除此之外不会造成任何限制。
然而,当我尝试
时inVectBroken : Elem 2 testVec
inVectBroken = There Here
我收到错误:
When checking an application of constructor There:
Type mismatch between
Elem x (x :: xs) (Type of Here)
and
Elem 2 [4, 5, 6] (Expected type)
Specifically:
Type mismatch between
2
and
4
有人可以向我解释上述代码是如何工作的(神奇地?)将There
限制在Vect
的尾部?
答案 0 :(得分:5)
Here 4 (x :: xs)
证明4位于(x :: xs)
的头部,因此x = 4
。 There
需要Elem 4 xs
证明xs
,{4}位于Elem 4 (y :: xs)
,因此证明y
,4仍然在扩展列表中的某个位置。这就是y
所在的地方。 in1 : Elem 4 (4 :: Nil)
in1 = Here
in2 : Elem 4 (3 :: 4 :: Nil)
in2 = There in1
in3 : Elem 4 (8 :: 4 :: Nil)
in3 = There in1
实际上是什么并不重要,它只是允许将证明扩展到更大的列表。例如:
@computedFrom
根据您看到的类型,不是元素4在整个证明中而是在列表中发生变化。