pas*_*ash 28 haskell type-systems ghc quantifiers type-extension
如果要使用GHC的词法范围变量,则还必须使用显式通用量化.也就是说,您必须向forall
函数的类型签名添加声明:
{-# LANGUAGE ExplicitForAll, ScopedTypeVariables #-}
f :: forall a . [a] -> [a] -- The `forall` is required here ...
f (x:xs) = xs ++ [x :: a] -- ... to relate this `a` to the ones above.
Run Code Online (Sandbox Code Playgroud)
这实际上与量化有什么关系,或者扩展编写者是否只是将forall
关键字作为一个方便的标记来应用新的,更广泛的范围?
换句话说,为什么我们不能forall
像往常一样抛弃?是不是很清楚函数体内注释中的类型变量是否引用了函数签名中同名的变量?或者打字会不会有问题或含糊不清?
pas*_*ash 25
是的,量词是有意义的,并且需要使类型有意义.
首先请注意,在Haskell中确实没有"未量化"类型签名.没有a的签名forall
实际上是隐式量化的.这段代码......
f :: [a] -> [a] -- No `forall` here ...
f (x:xs) = xs ++ [x :: a] -- ... or here.
Run Code Online (Sandbox Code Playgroud)
......真的意味着:
f :: forall a . [a] -> [a] -- With a `forall` here ...
f (x:xs) = xs ++ [x :: forall a . a] -- ... and another one here.
Run Code Online (Sandbox Code Playgroud)
那么让我们弄清楚这是什么意思.重要的是要注意a
签名for f
和for x
中命名的类型变量由单独的量词绑定.这意味着它们是不同的变量,尽管共享一个名称.所以上面的代码相当于:
f :: forall a . [a] -> [a]
f (x:xs) = xs ++ [x :: forall b . b] -- I've changed `a` to `b`
Run Code Online (Sandbox Code Playgroud)
由于名称有所区别,现在不仅清楚签名中的类型变量f
和x
不相关,而且可以是任何类型的x
声明的签名.但是,这是不可能的,因为必须具有绑定到特定类型时被施加到一个参数.事实上,类型检查器会拒绝此代码.x
x
a
f
另一方面,forall
签名中有一个f
...
f :: forall a . [a] -> [a] -- A `forall` here ...
f (x:xs) = xs ++ [x :: a] -- ... but not here.
Run Code Online (Sandbox Code Playgroud)
......在a
中上的签名x
是由量词之初约束f
的类型签名,所以这a
代表了同类型由称为变量表示的类型a
中f
的签名.
归档时间: |
|
查看次数: |
1541 次 |
最近记录: |