在此paper中,有一个具有以下签名的函数:
vreplicate :: forall a n . SNatI n => a -> Vec a n
此签名与没有forall
的签名之间有什么区别:
vreplicate :: SNatI n => a -> Vec a n
?我的印象是,没有forall
,它隐含意味着与前面的forall
命名所有类型变量相同。
答案 0 :(得分:10)
有两个重要案例包括forall
有所不同。第一个是forall
的位置可以改变类型的含义 - 如果它出现在箭头的左边,这意味着函数的参数比其他情况“更多态”。这种差异是一个基本的差异;但是,它似乎并不适用于此。
第二个区别是句法(而不是基本),即:在ScopedTypeVariables
存在的情况下,由forall
约束的变量打开一个打字范围,而变量隐式绑定没有forall
1}}不要。因此,在vreplicate
的正文中,可以使用类型变量a
和n
,并确保它们引用与vreplicate
签名中提到的相同类型。如果没有forall
(或没有ScopedTypeVariables
),则在a
正文中使用n
和vreplicate
会在全球范围内引入 fresh 量化变量,程序员有责任确保它们与vreplicate
签名中的类型统一,如果需要的话。有关详细信息,请参阅the documentation。
如果没有仔细阅读本文,我无法确定,但我坚决认为后者正在这里发生。