为什么这个简单的Morte程序不会进行类型检查?

时间:2015-11-17 10:32:03

标签: haskell types morte

我正试图通过Morte更好地理解建构的微积分。我的第一次尝试是调用身份功能本身。然而,

(
λ (idType : *) →
λ (id : idType) → 
(id idType))

(∀(t : *) → ∀(x : t) → t)
(λ(a : *) → λ(x : a) → x)

该程序无法编译错误:

Context:
idType : *
id : idType

Expression: id idType

Error: Only functions may be applied to values

这对我没有意义,因为id是函数(λ(a : *) → λ(x : a) → x),类型为idType == (∀(t : *) → t → t)。为什么我收到这个错误?

2 个答案:

答案 0 :(得分:4)

T = (λ (idType : *) →
     λ (id : idType) → 
    (id idType))

是错误的。否则T nat 4也会打字检查(假装我们有自然帮助直觉)。

如果你想编写一个应用程序函数(如Haskell的$),你可以使用

apply = 
    (λ (a b : *) →
     λ (f : a -> b) → 
     λ (x : a) → 
     f x)

请注意,上述内容仅适用于非依赖f。在依赖的情况下,b可能取决于类型a的实际值,使事情变得更加复杂,因为现在b是一个函数。

applyDep = 
    (λ (a : *) →
     λ (b : a -> *) →
     λ (f : ∀(x : a) -> b x) → 
     λ (x : a) → 
     f x)

一个例子(简化语法):

applyDep 
  Bool
  (λ (x : Bool) -> if x then Int else Char)
  (λ (x : Bool) -> if x then 4 else 'd')
  True

上面我对依赖函数(最后一个lambda)非常草率,因为if是错误类型的(分支的不同类型),但是你可能会得到粗略的想法。为了更精确地编写它,我需要类似于Coq具有的依赖匹配/案例(或依赖于Bool的依赖消除器):

fun x: Bool =>
  match x as y return (if y then Int else Char) with
  | True  => 3
  | False => 'a'
  end

在上面的“if”中,我必须清楚地表明两个分支的类型是不同的(Int vs Char),但是如果我们将其作为g x的结果,g = fun y => if y then Int else Char。基本上,结果类型现在取决于x值。

答案 1 :(得分:3)

这里的问题是教堂式的打字(这里是一个很好的blogpost和一些discussion),一切都必须从一开始就是好的打字:如果你的打字很好{{ 1}}和类型良好的f,然后您可以将x应用于f(如果类型匹配)。如果x的输入不是很好,那么它就不是一个合法的术语,即使可以为f分配类型,也会出现错误。

您的f x输入不是很好:λ (idType : *) → λ (id : idType) → (id idType)id类型的术语,它不是接收idType的函数,因此您无法应用它到*