在Towards Observational Type Theory的“5.完整OTT”部分的末尾,作者展示了如何在OTT中定义强制下构造函数索引数据类型。这个想法基本上是将索引数据类型转换为参数化,如下所示:
data IFin : ℕ -> Set where
zero : ∀ {n} -> IFin (suc n)
suc : ∀ {n} -> IFin n -> IFin (suc n)
data PFin (m : ℕ) : Set where
zero : ∀ {n} -> suc n ≡ m -> PFin m
suc : ∀ {n} -> suc n ≡ m -> PFin n -> PFin m
康纳还在observational type theory (delivery):
的底部提到了这种技巧当然,解决方法是做GADT人员做的事情并定义 归纳家庭明确提出命题平等。然后 当然,你可以通过变性来运输它们。
然而,Haskell中的类型检查器知道范围中的等式约束,并且在类型检查期间实际使用它们。例如。我们可以写
f :: a ~ b => a -> b
f x = x
它在类型理论中不起作用,因为在范围内有a ~ b
的证明不足以能够用这个等式重写:证明也必须是refl
,因为在错误假设的类型中,由于终止问题(类似this),检查变得不可判定。因此,当您在Haskell中Fin m
上的模式匹配时,m
会在每个分支中重写为suc n
,但这种情况在类型理论中不会发生,相反,您只需要明确证明suc n ~ m
。在OTT中,根本无法对证据进行模式匹配,因此您既不能假装证明refl
也不能实际要求。只能向coerce
提供证明或忽略它。
这使得编写涉及索引数据类型的任何内容变得非常困难。例如。向量的通常三行(包括类型签名)lookup
成为这个野兽:
vlookupₑ : ∀ {n m a} {α : Level a} {A : Univ α} -> ⟦ n ≅ m ⇒ fin n ⇒ vec A m ⇒ A ⟧
vlookupₑ p (fzeroₑ q) (vconsₑ r x xs) = x
vlookupₑ {n} {m} p (fsucₑ {n′} q i) (vconsₑ {m′} r x xs) =
vlookupₑ (left (suc n′) {m} {suc m′} (trans (suc n′) {n} {m} q p) r) i xs
vlookupₑ {n} {m} p (fzeroₑ {n′} q) (vnilₑ r) =
⊥-elim $ left (suc n′) {m} {0} (trans (suc n′) {n} {m} q p) r
vlookupₑ {n} {m} p (fsucₑ {n′} q i) (vnilₑ r) =
⊥-elim $ left (suc n′) {m} {0} (trans (suc n′) {n} {m} q p) r
vlookup : ∀ {n a} {α : Level a} {A : Univ α} -> Fin n -> Vec A n -> ⟦ A ⟧
vlookup {n} = vlookupₑ (refl n)
它可能有点简化,因为如果具有可判定的相等性的数据类型的两个元素明显相等,那么它们在通常的内涵意义上也是相等的,并且自然数确实具有可判定的相等性,因此我们可以强制所有这些方程式与其内部对应物和模式匹配,但这会破坏vlookup
的一些计算属性,无论如何都是冗长的。用不能确定平等的指数来处理更复杂的情况几乎是不可能的。
我的推理是否正确? OTT中的模式匹配如何工作?如果这确实是一个问题,有没有办法减轻它?
答案 0 :(得分:15)
我想我会说这个。我发现这是一个奇怪的问题,但那是因为我自己的特殊旅程。简短的回答是:不要在OTT或任何内核类型理论中进行模式匹配。这与不进行模式匹配是不一样的。
答案基本上都是我的博士论文。
在我的博士论文中,我将展示如何将以模式匹配风格编写的高级程序精心编写为内核类型理论,该理论仅具有归纳数据类型的归纳原则和对命题相等的适当处理。模式匹配的细化引入了数据类型索引上的命题方程,然后通过统一来解决它们。那时候,我正在使用内涵平等,但观察平等给你至少相同的力量。那就是:我的技术用于详细阐述模式匹配(从而使其不受核心理论的影响),隐藏所有等级的猪场 - 幼稚园,在升级到观察平等之前。您用来说明您的观点的可怕的vlookup可能对应于精化过程的输出,但输入不一定非常糟糕。好的定义
vlookup : Fin n -> Vec X n -> X
vlookup fz (vcons x xs) = x
vlookup (fs i) (vcons x xs) = vlookup i xs
详细阐述。沿途发生的方程求解与Agda在元级别上通过模式匹配或Haskell检查定义时所做的方程解决方法相同。不要被像
这样的程序所迷惑f :: a ~ b => a -> b
f x = x
在 kernel Haskell中,详细阐述了某种
f {q} x = coerce q x
但它不在你的脸上。它也不是编译代码。 OTT等式证明,如Haskell等式证明,可以在使用闭合术语进行计算之前删除。
Digression。要明确Haskell中的相等数据的状态,GADT
data Eq :: k -> k -> * where
Refl :: Eq x x
真的给你了
Refl :: x ~ y -> Eq x y
但由于类型系统在逻辑上不合理,因此类型安全依赖于该类型的严格模式匹配:您无法擦除Refl
并且您必须在运行时计算并匹配它,但是您< em>可以擦除与x~y
证明相对应的数据。在OTT中,整个命题片段对于开放项是证明无关的,并且对于闭合计算是可擦除的。 离题结束。
对此数据类型或该数据类型的相等性的可判定性并不特别相关(至少,如果您具有身份证明的唯一性,那么;如果您不总是具有UIP,则可判定性有时是获取它的一种方式)。模式匹配中出现的等式问题出现在任意 open 表达式上。这是很多绳索。但是机器当然可以决定片段,其中包含从变量和完全应用的构造函数构建的一阶表达式(这就是当你分割案例时Agda所做的事情:如果约束太奇怪,那就是barfs)。 OTT应该允许我们进一步推进高阶统一的可判定片段。如果您知道(forall x. f x = t[x])
未知f
,则相当于f = \ x -> t[x]
。
所以,“OTT中没有模式匹配”一直是一个深思熟虑的设计选择,因为我们一直希望它成为我们已经知道如何做的翻译的精心设计目标。相反,它是内核理论力量的严格升级。