是否可以在模式匹配中引用类型变量?

时间:2014-03-08 19:00:31

标签: haskell pattern-matching type-variables

以下代码(无意做任何有用的事情)编译得很好:

{-# LANGUAGE ScopedTypeVariables #-}
import System.Random

uselessFunction :: (RandomGen g) => g -> [Int]
uselessFunction gen = 
  let (value::Int, newGen) = (random gen)
  in (uselessFunction newGen)

我是否可以在模式匹配中使用类型变量,具体如下(代码无法编译):

{-# LANGUAGE ScopedTypeVariables #-}
import System.Random

uselessFunction :: (RandomGen g, Random a) => g -> [a]
uselessFunction gen = 
  let (value::a, newGen) = (random gen)
  in (uselessFunction newGen)

3 个答案:

答案 0 :(得分:8)

您已经注意到ScopedTypeVariables扩展名允许您在模式上添加类型注释。但是对于扩展的 main 目的,要使一个类型变量在本地作用域,以便您可以在函数内部引用它,您还必须在类型声明中使用forall声明它,如下所示: / p>

uselessFunction :: forall a g. (RandomGen g, Random a) => g -> [a]

这不会改变声明本身的含义,但暗示GHC您可能希望在本地使用该变量。

答案 1 :(得分:2)

http://youtu.be/52VsgyexS8Q。这篇简短的YouTube教程使用范围类型变量。非常有用。

答案 2 :(得分:0)

Type Variables in Patterns, by Richard A. Eisenberg, Joachim Breitner, Simon Peyton Jones中描述了解决问题的方法:

  

多年来,GHC对Haskell实施了扩展,   允许将类型变量绑定到类型签名和模式中,以及   超出条款范围。从未正确指定此扩展名。我们   在这里纠正这种疏忽。有了正式的规范,   绑定类型设计的迷宫式路径   模式中的变量变得非常清晰。因此,我们扩展了   ScopedTypeVariables显式绑定类型变量,从而避免了   替代性解决方案,可以解决历史上的垃圾箱。