Haskell类型推断

Nie*_*and 6 haskell ghc

当我在Haskell中检查函数类型时:t,例如我之前的问题中的那些,我倾向于得到如下结果:

Eq a => a -> [a] -> Bool
(Ord a, Num a, Ord a1, Num a1) => a -> a1 -> a
(Num t2, Num t1, Num t, Enum t2, Enum t1, Enum t) =>  [(t, t1, t2)]
Run Code Online (Sandbox Code Playgroud)

看起来这不是一个微不足道的问题 - Haskell解释器如何选择文字来象征类型类?什么时候会选择a而不是t?什么时候会选择a1而不是b?程序员的观点是否重要?

Bak*_*riu 8

类型变量的名称并不重要.类型:

Eq element => element -> [element] -> Bool
Run Code Online (Sandbox Code Playgroud)

完全相同:

Eq a => a -> [a] -> Bool
Run Code Online (Sandbox Code Playgroud)

有些名称更容易阅读/记忆.

现在,推理器如何为类型选择最佳名称?

免责声明:我绝对不是 GHC开发人员.但是我正在为我的学士论文中的Haskell开发一个类型推理器.

在推理期间,为变量选择的名称可能不是那么可读.事实上,他们几乎是肯定的线沿线的东西_NN一个数字或aNN一个数字.

这是因为您经常需要"刷新"类型变量才能完成推理,因此您需要一种快速创建新名称的方法.为此,使用编号变量非常简单.

推理完成时显示的名称可以"漂亮打印".该inferencer可以重命名变量使用a,b,c等来代替上_1,_2等等.

诀窍是大多数操作都有明确的类型签名.一些定义需要确定一些类型的变量(class,datainstance举例).用户明确提供的所有这些名称都可用于以更好的方式显示类型.

在推理时,您可以以某种方式跟踪新鲜类型变量的来源,以便能够在向用户显示时更加明智地重命名它们.另一种选择是通过向它们添加数字来刷新变量.例如,一种新的类型return可能是Monad m0 => a0 -> m0 a0(在这里我们知道使用m并且a仅仅因为class定义Monad使用这些名称).推理完成后,你可以摆脱数字并获得漂亮的名字.

通常,推理器将尝试使用通过签名明确提供的名称.如果已经使用了这样的名称,它可能决定添加一个数字而不是使用不同的名称(例如,使用b1而不是cif b已经绑定).

可能还有其他一些临时规则.例如一个事实,即元组的元件具有类似t,t1,t2,t3等内很可能有一个自定义规则来完成.实际上t并没有出现在(,,)例如签名中.