我正在关注令人惊叹的TDDwI,写一个简单的removeElem
。
关于它的四个问题:
为什么我可以为同一模式编写3个声明?
absurd
和impossible
之间有什么区别?
在返回[]
的第3个案例中,[]
是一个值,因此......证明xs
有a
要删除,并且......对吧?
如果我删除它们中的所有3个,那么该函数仍然是完全的,并且我有一个令人费解的痒,这是一些奇怪的事情。 ?。 (我认为这是一个问题)
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
答案 0 :(得分:1)
情况是不可能的,所以你做什么并不重要。如果一个等于2,那么月亮由奶酪制成是一个真实的陈述,因为一个不等于两个。 absurd
是Uninhabited 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
,其内容为"如果类型t
无人居住且您拥有该类型的居民,那么您可以构建一个居民< em>任意类型a
&#34;。因此,您只需要Elem x []
来实现该界面(它是here)。这就是absurd later
工作的原因。
impossible
有效,因为Idris能够独立完成上述所有推理。
absurd
和impossible
之间的区别是什么?
impossible
关键字可用于排除不进行类型检查的案例,而absurd
只是引理 ,所以如果你使用它,一切都必须检查。
在返回
[]
的第3个案例中,[]
是一个值,因此......证明xs
有a
要删除,并且......正确?
是的,这是正确的。 removeElem
获取一个值,一个正长度的向量,证明该值属于向量并返回逐个减少的向量的向量。如果你采用单元素向量,你可以忽略值和证明并立即返回空向量。我的观点是,您不必使用证明,它会为您提供额外的保证,但您可以随意忽略它们。
如果我删除它们中的所有3个,那么该函数仍然是完全的,并且我有一个令人费解的痒痒,这是一些奇怪的事情
这里的一切都很好,功能仍然有效--Idris让你省略不可能的情况:
removeElem {n = Z} value (y :: []) (There later) impossible