Ste*_*314 4 polymorphism haskell typeclass ghc
以下内容来自GHC用户指南(Haskell Platform 2012.4.0.0)...
7.6.1.3.类方法类型
Haskell 98禁止类方法类型提及类类型变量的约束,因此:
Run Code Online (Sandbox Code Playgroud)class Seq s a where fromList :: [a] -> s a elem :: Eq a => a -> s a -> Boolelem的类型在Haskell 98中是非法的,因为它包含约束Eq a,仅约束类类型变量(在本例中为a).GHC解除了这一限制(flag -XConstrainedClassMethods).
但是,我没有看到任何解释这意味着什么.我可以看到两种可能性......
Seq类型的类隐式斩获Eq a来自约束elem.elem方法不能用于类型类Seq在的情况下a是不类的成员Eq(或其中它是一个部件,但是其中这是未知的elem时).我强烈怀疑(2)因为它似乎有用,而(1)似乎没用.(2)基本上允许为可以支持它们的情况定义方法,而不限制类型类仅为这些情况实例化.
这个例子似乎正是在激发这一点 - 这个想法elem通常对于序列来说是一个有用的操作,对于没有它们来说太有价值,但我们也想要支持那些elem不受支持的序列,例如函数序列.
我是对的,还是我错过了什么?这个扩展的语义是什么?
注意:似乎GHC> = 7中存在一个错误,即使在Haskell 98模式下GHC也接受约束类方法.
此外,MultiParamTypeClasses无论ConstrainedMethodTypes扩展是否打开(也可能是错误),启用时都会始终接受手册中的示例.
在以下类型elem:
elem :: Eq a => a -> s a -> Bool
Run Code Online (Sandbox Code Playgroud)
a并且s是类类型变量,并且Eq a是类类型变量的约束a.正如手册所说,Haskell 98禁止这样的约束(FWIW,它也禁止多参数类型).因此,在Haskell 98模式下不应接受以下代码(我认为在Haskell 2010中也禁止它):
class Compare a where
comp :: Eq a => a -> a -> Bool
Run Code Online (Sandbox Code Playgroud)
事实上,GHC 6.12.1拒绝它:
Prelude> :load Test.hs
[1 of 1] Compiling Main ( Test.hs, interpreted )
Test.hs:3:0:
All of the type variables in the constraint `Eq a'
are already in scope (at least one must be universally quantified here)
(Use -XFlexibleContexts to lift this restriction)
When checking the class method: comp :: (Eq a) => a -> a -> Bool
In the class declaration for `Compare'
Failed, modules loaded: none.
Prelude> :set -XConstrainedClassMethods
Prelude> :load Test.hs
[1 of 1] Compiling Main ( Test.hs, interpreted )
Ok, modules loaded: Main.
Run Code Online (Sandbox Code Playgroud)
我们的想法是应该使用超类约束:
class (Eq a) => Compare a where
comp :: a -> a -> Bool
Run Code Online (Sandbox Code Playgroud)
关于语义,您可以轻松检查类方法约束是否使用以下代码隐式添加超类约束:
{-# LANGUAGE ConstrainedClassMethods #-}
module Main where
class Compare a where
comp :: (Eq a) => a -> a -> Bool
someMethod :: a -> a -> a
data A = A deriving Show
data B = B deriving (Show,Eq)
instance Compare A where
comp = undefined
someMethod A A = A
instance Compare B where
comp = (==)
someMethod B B = B
Run Code Online (Sandbox Code Playgroud)
使用GHC 6.12.1进行测试:
*Main> :load Test.hs
[1 of 1] Compiling Main ( Test.hs, interpreted )
Ok, modules loaded: Main.
*Main> comp A
<interactive>:1:0:
No instance for (Eq A)
arising from a use of `comp' at <interactive>:1:0-5
Possible fix: add an instance declaration for (Eq A)
In the expression: comp A
In the definition of `it': it = comp A
*Main> someMethod A A
A
*Main> comp B B
True
Run Code Online (Sandbox Code Playgroud)
答:不,它没有.约束仅适用于具有约束类型的方法.所以你是对的,这是#2的可能性.