如何输入简单类型的lambda演算项(S K K)

时间:2016-03-10 00:20:44

标签: haskell lambda functional-programming k-combinator s-combinator

我正在尝试实现一个简单类型的lambda演算类型检查器。在运行完整性测试时,我尝试输入(S K K)并且我的类型检查器抛出此错误:

TypeMismatch {firstType = t -> t, secondType = t -> t -> t}

违规期限显然是(S K K)

(\x:t -> t -> t.\y:t -> t.\z:t.x z (y z)) (\x:t.\y:t.x) (\\x:t.\y:t.x)

我认为问题源于缺乏多态性,因为当我输入检查这个haskell代码时它工作正常:

k x y = x
s x y z = x z (y z)
test = s k k -- type checks

但如果我专注于这种类型:

k :: () -> () -> ()
k x y = x
s :: (() -> () -> ()) -> (() -> ()) -> () -> ()
s x y z = x z (y z)
test = s k k -- doesn't type check 

仅供参考,我的类型系统很简单:

data Type = T | TArr Type Type

full source

1 个答案:

答案 0 :(得分:9)

我将窃取a previous answer of mine中的想法,以展示如何向您提出问题。但首先我要稍微重新阐述你的问题。

在Haskell,我们有

s k k

我们要问的问题是"在类型检查s :: (a -> b -> c) -> (a -> b) -> (a -> c) k :: d -> e -> d k :: f -> g -> f s k k :: h 之后这些类型是什么样的?"。更重要的是,如果我们用不同的统一变量重写它们,

s

然后问题就变成了统一问题:我们试图将(d -> e -> d) -> (f -> g -> f) -> h的类型统一为它所使用的类型 - 即> :{ | :t undefined | :: ((a -> b -> c) -> (a -> b) -> (a -> c)) | ~ ((d -> e -> d) -> (f -> g -> f) -> h) | => (a, b, c, d, e, f, g, h) | :} undefined :: ((a -> b -> c) -> (a -> b) -> (a -> c)) ~ ((d -> e -> d) -> (f -> g -> f) -> h) => (a, b, c, d, e, f, g, h) :: (f, g -> f, f, f, g -> f, f, g, f -> f) 。现在我们手头有一个统一问题,我们可以用我的另一个答案中显示的格式询问:

T

现在我们可以看到你的版本无法正常工作的原因:在你的版本中,你已经将所有多态变量实例化为基类型b ~ g -> f;但由于e ~ g -> fh ~ f -> ff显然属于箭头类型,因此肯定无法正常工作!但是,如果我们尊重上述替换,gf ~ T的任何选择都将有效;特别是如果我们选择g ~ Ts :: (T -> (T -> T) -> T) -> (T -> (T -> T)) -> (T -> T) k1 :: T -> (T -> T) -> T k2 :: T -> T -> T s k1 k2 :: T -> T ,那么我们有

{{1}}