Haskell 布尔和STLC的Church编码

Haskell 布尔和STLC的Church编码,haskell,data-kinds,church-encoding,Haskell,Data Kinds,Church Encoding,人们常说 tru t f = t fls t f = f 表示True和False,即“我们可以使用这些术语来执行测试布尔值真值的操作” 但这隐藏了一个重要的警告,因为它似乎只适用于非类型lambda演算。如果我只是将这些值插入haskell,我可以编写一个函数: tryMeOnFalse ∷ (∀ t f. t → f → t) → String tryMeOnFalse tr = "Hi" a' = tryMeOnFalse tru b' = tryMeOnFalse fls -- t

人们常说

tru t f = t
fls t f = f
表示True和False,即“我们可以使用这些术语来执行测试布尔值真值的操作”

但这隐藏了一个重要的警告,因为它似乎只适用于非类型lambda演算。如果我只是将这些值插入haskell,我可以编写一个函数:

tryMeOnFalse ∷  (∀ t f. t → f → t) → String
tryMeOnFalse tr = "Hi"
a' = tryMeOnFalse tru
b' = tryMeOnFalse fls  -- type error !
这在类型级别上区分了tru和fls。如果说:

  • 在STLC
    tru
    fls
    中,是一些提升的
    'Boolean
    类型的值级见证,其类型有
    'True
    'False
  • 在STLC中,(强制的)类型值
    (tru::∀ t.t→ T→ t) 
    (fls::∀ t.t→ T→ t) 
    表示真与假(在非类型中,通常是这样)

编辑:多亏了@Daniel Wagner的回答,我现在意识到我在思考二阶Lambda演算,而不是问题中的STLC。

这不仅适用于非类型Lambda演算;但在类型化结石中,人们确实需要像往常一样小心地打字。我们应该界定:

type Boolean = forall r. r -> r -> r
我们当然有
tru,fls::Boolean
,并且应该这样注释它们。 但是我们没有
trymeonflse::Boolean->String
!所以这里没有真正的矛盾

你对STLC的评论有点奇怪,因为STLC有一个非常不同的类型系统。我们需要为每个结果类型提供单独的布尔类型,因为不存在多态性


在Haskell中,我们当然可以定义仅由
tru
fls
居住的类型(当然,每个类型也由
未定义的
居住);但这通常不是很有用。

我想我把STLC和二阶类型的微积分混淆了。当您定义
类型Boolean=forall r时。r->r->r
您也在使用它。“二阶类型演算”的典型名称是System F,仅供参考