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

标签 haskell types type-variables

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

{-# LANGUAGE ScopedTypeVariables #-}

char = case Just '3' of 
    Just (x :: Char) -> x
    Nothing          -> '?'

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

此外,加载 ScopedTypeVariables 而不同时加载 ExplicitForAll 有什么影响? ScopedTypeVariables 的所有其他用例似乎都需要 ExplicitForAll 才能实际工作。但是在上面的代码片段中,没有 ExplicitForAll

最佳答案

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

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

f (Just (x::a)) = bob
  where
    bob::[a]
    bob = [x]

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

编辑

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

关于Haskell:模式匹配类型注释中需要ScopedTypeVariables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29395265/

相关文章:

haskell - 将 optparse-applicative 与多个子命令和全局选项一起使用

scala - scala中的匹配类型

c - 格式 '%s' 需要类型为 'char *' 的参数,但参数 3 在 fprintf 中具有类型 'int' [-Wformat]

haskell - 如何正确绑定(bind)此类型变量?

generics - Swift 通用类型变量应遵守协议(protocol)(类型类)

python - 签名中带有 TypeVar 的协议(protocol)的实现者不能使用自己的类型

haskell - 理解类型错误 : "expected signature Int*Int->Int but got Int*Int->Int"

haskell - 如何指示 Haskell 包处于 alpha/beta/release candidate 阶段?

Haskell:函数组合导致类型不匹配错误

C、 "extern"硬件抽象层变量类型