So
类型的预期目的是什么?将其译为Agda:
data So : Bool → Set where
oh : So true
So
将布尔命题提升为逻辑命题。Oury和Swierstra的入门论文The Power of Pi给出了一个以表格列索引的关系代数的示例。取两个表格的乘积需要它们拥有不同的列,对此他们使用了So
:
Schema = List (String × U) -- U is the universe of SQL types
-- false iff the schemas share any column names
disjoint : Schema -> Schema -> Bool
disjoint = ...
data RA : Schema → Set where
-- ...
Product : ∀ {s s'} → {So (disjoint s s')} → RA s → RA s' → RA (append s s')
我习惯于为我想证明的有关程序的事情构建证据条款。构建逻辑关系以确保Schema的不相交似乎更自然:
Disjoint : Rel Schema _
Disjoint s s' = All (λ x -> x ∉ cols s) (cols s')
where cols = map proj₁
So
和“proper”证明项相比似乎有严重的劣势:在oh
上进行模式匹配不会给你任何信息,你不能使用这些信息来检查另一个术语的类型(是吗?)- 这意味着So
值不能有效地参与交互式证明。相比之下,Disjoint
的计算效用很有用,它被表示为每一列都不出现在s
中的证明列表。
我并不真正相信规范So (disjoint s s')
比Disjoint s s'
更简单易写 - 您必须在没有类型检查器帮助的情况下定义布尔函数disjoint
- 而且无论如何,Disjoint
在您想要操作其中包含的证据时会很有用。
我还怀疑当您构造一个Product
时,So
是否节省了精力。为了给出So (disjoint s s')
的值,您仍然需要在s
和s'
上进行足够的模式匹配,以满足类型检查器它们实际上是不相交的。抛弃这样生成的证据似乎是一种浪费。
So
对于部署它的代码的作者和用户来说都不太方便。那么,在什么情况下我会想要使用So
呢?
data
类型和函数递归定义的关系。你能详细说明为什么 Agda 可以推断使用你的定义来创建So
值,但不能用我的定义创建呢? - Benjamin Hodgsondata
和record
之间的区别方面,后者具有 eta,而前者则没有。⊤
的任何居民都与tt
在定义上是相等的:eq: ∀ {x} -> x ≡ tt; eq = refl
,因此当 Agda 遇到_x: ⊤
,其中_x
是一个元变量时,_x
将被实例化为tt
,并且解决了统一问题。但是当 Agda 遇到_x: So true
时,她无法将_x
与某些内容统一起来,因为这种机制对于“数据”不起作用。但是,您可以使用实例参数强制执行统一,如上所述。 - effectfully