理解两个Haskell签名之间的区别,一个使用forall

时间:2015-11-06 22:28:29

标签: haskell

在此paper中,有一个具有以下签名的函数:

vreplicate :: forall a n . SNatI n => a -> Vec a n 

此签名与没有forall的签名之间有什么区别:

vreplicate :: SNatI n => a -> Vec a n 

?我的印象是,没有forall,它隐含意味着与前面的forall命名所有类型变量相同。

1 个答案:

答案 0 :(得分:10)

有两个重要案例包括forall有所不同。第一个是forall的位置可以改变类型的含义 - 如果它出现在箭头的左边,这意味着函数的参数比其他情况“更多态”。这种差异是一个基本的差异;但是,它似乎并不适用于此。

第二个区别是句法(而不是基本),即:在ScopedTypeVariables存在的情况下,由forall约束的变量打开一个打字范围,而变量隐式绑定没有forall 1}}不要。因此,在vreplicate的正文中,可以使用类型变量an,并确保它们引用与vreplicate签名中提到的相同类型。如果没有forall(或没有ScopedTypeVariables),则在a正文中使用nvreplicate会在全球范围内引入 fresh 量化变量,程序员有责任确保它们与vreplicate签名中的类型统一,如果需要的话。有关详细信息,请参阅the documentation

如果没有仔细阅读本文,我无法确定,但我坚决认为后者正在这里发生。