“有”在idris教程,第11页,第3.4.4节中如何工作?

时间:2016-01-21 11:01:41

标签: idris

以下是教程中的示例,为简单起见略作修改:

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的尾部?

1 个答案:

答案 0 :(得分:5)

Here 4 (x :: xs)证明4位于(x :: xs)的头部,因此x = 4There需要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在整个证明中而是在列表中发生变化。