为什么这些声明(对于相同的模式)满足类型检查器?

时间:2017-10-04 01:53:15

标签: types idris proof-of-correctness

我正在关注令人惊叹的TDDwI,写一个简单的removeElem

关于它的四个问题:

  1. 为什么我可以为同一模式编写3个声明?

  2. absurdimpossible之间有什么区别?

  3. 在返回[]的第3个案例中,[]是一个值,因此......证明xsa要删除,并且......对吧?

  4. 如果我删除它们中的所有3个,那么该函数仍然是完全的,并且我有一个令人费解的痒,这是一些奇怪的事情。 ?。 (我认为这是一个问题)

  5. removeElem : (value : a)
              -> (xs : Vect (S n) a) 
              -> (prf : Elem value xs) 
              -> Vect n a
    removeElem value (value :: ys) Here = ys
    removeElem {n = Z} value (y :: []) (There later) = absurd later -- ??
    removeElem {n = Z} value (y :: []) (There later) impossible     -- ??
    removeElem {n = Z} value (y :: []) (There later) = []           -- ??
    removeElem {n = (S k)} value (y :: ys) (There later) = 
      y :: removeElem value ys later
    

2 个答案:

答案 0 :(得分:1)

情况是不可能的,所以你做什么并不重要。如果一个等于2,那么月亮由奶酪制成是一个真实的陈述,因为一个不等于两个。 absurdUninhabited t => t -> a类型的函数。伊德里斯知道情况是不可能的,所以你不必处理它。

你甚至可以返回字符串"嗨"通过证明Vect 0 a = String

removeElem : (value : a)
    -> (xs : Vect (S n) a) 
    -> (prf : Elem value xs) 
    -> Vect n a
removeElem value (value :: ys) Here = ys
removeElem {n = Z} value (y :: []) (There later) = absurd later -- ??
removeElem {n = Z} value (y :: []) (There later) impossible     -- ??
removeElem {a} {n = Z} value (y :: []) (There later) = rewrite (the (Vect 0 a = String) (absurd later)) in "Hi"           -- ??
removeElem {n = (S k)} value (y :: ys) (There later) = y :: removeElem value ys later

答案 1 :(得分:1)

  

为什么我可以为同一模式写3个声明?

因为在这种情况下(y :: [])你正在处理一个单元素向量。 这意味着later的类型为Elem value [],即空列表中有一个元素value,即荒谬。回想一下,absurd的类型为Uninhabited t => t -> a,其内容为&#34;如果类型t无人居住且您拥有该类型的居民,那么您可以构建一个居民< em>任意类型a&#34;。因此,您只需要Elem x []来实现该界面(它是here)。这就是absurd later工作的原因。

impossible有效,因为Idris能够独立完成上述所有推理。

  

absurdimpossible之间的区别是什么?

impossible 关键字可用于排除不进行类型检查的案例,而absurd只是引理 ,所以如果你使用它,一切都必须检查。

  

在返回[]的第3个案例中,[]是一个值,因此......证明xsa要删除,并且......正确?

是的,这是正确的。 removeElem获取一个值,一个正长度的向量,证明该值属于向量并返回逐个减少的向量的向量。如果你采用单元素向量,你可以忽略值和证明并立即返回空向量。我的观点是,您不必使用证明,它会为您提供额外的保证,但您可以随意忽略它们。

  

如果我删除它们中的所有3个,那么该函数仍然是完全的,并且我有一个令人费解的痒痒,这是一些奇怪的事情

这里的一切都很好,功能仍然有效--Idris让你省略不可能的情况:

removeElem {n = Z} value (y :: []) (There later) impossible