Haskell:模式匹配类型注释中需要 ScopedTypeVariables

CMC*_*kai 3 haskell types type-variables

为什么这段代码需要ScopedTypeVariables扩展?

{-# LANGUAGE ScopedTypeVariables #-}

char = case Just '3' of 
    Just (x :: Char) -> x
    Nothing          -> '?'
Run Code Online (Sandbox Code Playgroud)

当我阅读关于 的文档时ScopedTypeVariables,这似乎意味着将函数体中的类型变量与父函数签名统一起来。不过,这段代码片段并没有统一任何类型变量!

另外加载ScopedTypeVariables而不加载的效果是什么ExplicitForAll?所有其他用例ScopedTypeVariables似乎都需要ExplicitForAll实际工作。但是在上面的代码段中,没有ExplicitForAll.

dfe*_*uer 5

ScopedTypeVariablesExplicitForAll自动启用为了您的理智,我建议ScopedTypeVariables在使用任何其他类型系统扩展时始终使用(除了可能只处理类/实例/上下文的那些)并且永远不要ExplicitForAll直接使用。

ScopedTypeVariables需要模式变量签名的原因只是这样的签名是扩展的一部分。在其他用途​​中,它们为您提供了一种将类型变量引入作用域的方法。例如:

f (Just (x::a)) = bob
  where
    bob::[a]
    bob = [x]
Run Code Online (Sandbox Code Playgroud)

我不知道为什么模式签名ScopedTypeVariables本身就是 的一部分;它们很可能是为此目的而创建的,并且所有代码都是一次性编写的。将它们分开以进行正交扩展几乎肯定会被认为比它的价值更麻烦。

编辑

事实上,有一个很好的理由。除了模式绑定之外,模式签名中的类型变量被泛化,将该变量带入作用域。所以在上面的例子中,你不需要知道a外部类型环境中是否有一个。如果您可以在没有范围类型变量的情况下启用模式签名,则可以根据是否打开范围类型变量来对变量进行泛化。对于ExplicitForAllwithoutScopedTypeVariables也会发生同样的混乱,这就是为什么我想终止该扩展并使其ScopedTypeVariables成为默认值,或者至少使用当前启用的扩展自动打开它ExplicitForAll

  • 实际上,GHC 6.8.1 是第一个拥有 `LANGUAGE` pragma 系统的版本,同时具有 `ScopedTypeVariables` 和 `PatternSignatures`。后者已从 7.0.1 中的文档中删除,但您仍然可以提供它并获得弃用警告,告诉您改用 `ScopedTypeVariables`。 (2认同)