为什么这个相互递归的数据定义不完整,我该如何解决?

时间:2016-07-21 19:36:31

标签: idris

我最近正在尝试使用Idris,并提出了以下“类型级别定义”:

mutual
  data Set : Type -> Type where
    Empty : Set a
    Insert : (x : a) -> (xs : Set a) -> Not (Elem x xs) -> Set a

  data Elem : (x : a) -> Set a -> Type where
    Here : Elem x (Insert x xs p)
    There : Elem x xs -> Elem x (Insert y xs p)

所以一个集合是空的,或者它由一个集合和一个已被证明不在该集合中的附加元素组成。

当我总结检查时,我收到错误

  

[...]并非严格正面

代表InsertHereThere。我一直在搜索文档中的“严格正面”和整体检查器这样的术语,但我无法弄清楚为什么这种情况特别不完全(或严格来说是正面的)。有人可以解释一下吗?

接下来的自然问题当然是如何“修复”它。我可以以某种方式更改定义,保持其语义,以便进行全局检查吗?

因为我真的不需要这个定义看起来像这样(毕竟它只是一个实验),所以知道是否有另一种,某种更惯用的方式来表示类型级别的集合也是很有趣的。总

1 个答案:

答案 0 :(得分:1)

This SO post解释了严格的积极类型及其重要性。在您的情况下,由于Not (Elem x xs)仅表示函数Elem x xs -> Void,因此这是“箭头左侧发生的类型”来自的地方。

你能用这样的东西做什么吗?

mutual
  data Set : Type -> Type where
    Empty : Set a
    Insert : (x : a) -> (xs : Set a) -> NotElem x xs -> Set a

  data NotElem : (x : a) -> Set a -> Type where
    NotInEmpty : NotElem x Empty
    NotInInsert : Not (x = y) -> NotElem x ys -> NotElem x (Insert y ys p)