那么:重点是什么?

时间:2015-10-21 22:57:37

标签: functional-programming agda dependent-type idris

So类型的目的是什么?音译成阿格达:

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似乎有一个严重的缺点,因为"适当的"证明术语:oh上的模式匹配并不能为您提供任何可以进行其他术语类型检查的信息(是吗?) - 这意味着So值可以'有用地参与互动证明。将此与Disjoint的计算有用性进行对比,s'表示为s中的每一列都不会出现在So (disjoint s s')中的证明列表。

我真的不相信规范Disjoint s s'disjoint更容易编写 - 您必须在没有类型检查器帮助的情况下定义布尔Disjoint函数 - 并且在任何情况下So在您想要操纵其中包含的证据时都会为自己付出代价。

我也怀疑Product在您构建So (disjoint s s')时节省了工作量。为了给出s的值,您仍然必须在s'So上进行足够的模式匹配,以满足类型检查器它们实际上是不相交的。丢弃由此产生的证据似乎是浪费。

{p> So对于部署的代码的作者和用户来说似乎都很笨拙。 '所以',在什么情况下我想使用let storyboard = UIStoryboard(name: "Main", bundle: nil) let destinationViewController: ViewController = storyboard.instantiateViewControllerWithIdentifier(identifier) self.navigationController?.pushViewController(destinationViewController, animated: true)

1 个答案:

答案 0 :(得分:14)

如果您已经拥有b : Bool,则可以将其变为命题:So b,这比b ≡ true短一点。有时(我不记得任何实际情况)没有必要打扰正确的数据类型,这个快速解决方案就足够了。

  与“适当”相比,

So似乎有严重的缺点   证明术语:oh上的模式匹配不会为您提供任何信息   您可以使用它来进行另一个术语类型检查。作为推论,   So值无法有效参与交互式证明。   将此与Disjoint的计算有用性进行对比   表示为s'中每列不包含的证明列表   出现在s

So确实为您提供了与Disjoint相同的信息 - 您只需要提取它即可。基本上,如果disjointDisjoint之间没有不一致,那么您应该能够使用模式匹配,递归和不可能的情况消除来编写函数So (disjoint s) -> Disjoint s

但是,如果你稍微调整一下这个定义:

So : Bool -> Set
So true  = ⊤
So false = ⊥

So成为非常有用的数据类型,因为x : So true由于tt的eta规则而立即缩减为。这允许像约束一样使用So:在伪Haskell中我们可以编写

forall n. (n <=? 3) => Vec A n

并且如果n是规范形式(即suc (suc (suc ... zero))),则编译器可以检查n <=? 3并且不需要证明。在实际的Agda中它是

∀ {n} {_ : n <=? 3} -> Vec A n

我在this回答中使用了这个技巧(那里是{_ : False (m ≟ 0)})。我想如果没有这个简单的定义,就不可能写出一个可用的机器版本here

Is-just : ∀ {α} {A : Set α} -> Maybe A -> Set
Is-just = T ∘ isJust

其中T是Agda标准库中的So

此外,在存在实例参数So的情况下,as-a-data-type可以用作So - 作为约束:

open import Data.Bool.Base
open import Data.Nat.Base
open import Data.Vec

data So : Bool -> Set where
  oh : So true

instance
  oh-instance : So true
  oh-instance = oh

_<=_ : ℕ -> ℕ -> Bool
0     <= m     = true
suc n <= 0     = false
suc n <= suc m = n <= m

vec : ∀ {n} {{_ : So (n <= 3)}} -> Vec ℕ n
vec = replicate 0

ok : Vec ℕ 2
ok = vec

fail : Vec ℕ 4
fail = vec