Haskell类型级lambda演算错误(或缺少)

时间:2017-07-26 01:19:15

标签: haskell ghc ghci

我一直在type arithmetic上阅读Haskell wiki中的页面,并且在类型系统中嵌入lambda演算的部分遇到了一些麻烦。从那一节开始,我收集到以下代码不适用于GHC / GHCi - 显然GHC不应该能够确定g的类型签名。

{-# OPTIONS -fglasgow-exts #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}

data X
data App t u
data Lam t

class Subst s t u | s t -> u
instance Subst X u u
instance (Subst s u s', Subst t u t') => Subst (App s t) u (App s' t')
instance Subst (Lam t) u (Lam t)

class Apply s t u | s t -> u
instance (Subst s t u, Eval u u') => Apply (Lam s) t u'

class Eval t u | t -> u
instance Eval X X
instance Eval (Lam t) (Lam t)
instance (Eval s s', Apply s' t u) => Eval (App s t) u

f :: Eval (App (Lam X) X) u => u
f = undefined
g :: Eval (App (Lam (App X X )) (Lam (App X X ))) u => u
g = undefined

请注意,我必须添加FlexibleContexts和UndecidableInstances,因为如果没有这些扩展,给定的代码似乎没有编译。但是,当我使用GHCi(版本8.0.2)运行时,我得到以下结果:

*Main> :t f
f :: X
*Main> :t g
g :: u

这对我来说特别奇怪,因为类型u没有在任何地方定义。这是上面两个语言扩展相互交互和glasgow-exts的结果吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:5)

类型where_exp只是一个孤独的变量 - 就像u中的a一样。

要真正将其归结为其基本要素,请考虑以下备用文件:

undefined :: a

如果您在ghci中询问{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE FlexibleInstances #-} class Loopy a instance Loopy a => Loopy a x :: Loopy a => a x = undefined 的类型,它会告诉您它的类型为x,没有上下文。这看起来有点神奇;你只需要意识到GHC中的实例解析完全被允许递归,并且实现很大程度上支持这一点。

如果您愿意,我们可以详细介绍您的示例中发生的情况,但它与上述文件非常类似。以下是详细信息。

所以,我们想看看是否允许我们拥有这个实例:

a

我们知道

Eval (App (Lam (App X X)) (Lam (App X X))) u

因此,只要我们同时拥有这两项内容,我们就可以拥有它:

instance (Eval s s', Apply s' t u) => Eval (App s t) u

第一个很容易,因为:

Eval (Lam (App X X)) s'
Apply s' (Lam (App X X)) u

所以当我们拥有时,我们可以获得蛋糕:

instance Eval (Lam t) (Lam t)

由于

Apply (Lam (App X X)) (Lam (App X X)) u
找到我们的蛋糕,我们应该检查下这两块石头:

instance (Subst s t u, Eval u u') => Apply (Lam s) t u'

Subst (App X X) (Lam (App X X)) u
Eval u u'

我们知道我们可以有蛋糕了

instance (Subst s u s', Subst t u t') => Subst (App s t) u (App s' t')

这很容易取得进展,因为:

Subst X (Lam (App X X)) s'
Subst X (Lam (App X X)) t'
Eval (App s' t') u'

因此,我们可以随时拥有原始实例:

instance Subst X u u

但是,嘿,presto!这是我们正在寻找的原始实例。总而言之,只要我们拥有原始实例,我们就可以拥有原始实例。所以我们声明我们可以拥有原始实例,然后我们可以拥有原始实例!不是那个桃子。