以下引自 GHC 用户指南(Haskell Platform 2012.4.0.0)...
7.6.1.3. Class method types
Haskell 98 prohibits class method types to mention constraints on the class type variable, thus:
class Seq s a where fromList :: [a] -> s a elem :: Eq a => a -> s a -> Bool
The type of elem is illegal in Haskell 98, because it contains the constraint Eq a, constrains only the class type variable (in this case a). GHC lifts this restriction (flag -XConstrainedClassMethods).
但是,我没有看到任何关于这意味着什么的解释。我可以看到两种可能性...
Seq
类型类隐式获得 Eq a
来自 elem
的约束. elem
方法不能用于类型类 Seq
在 a
的情况下不是 Eq
类的成员(或者它是一个成员,但不知道在哪里使用 elem
)。 我强烈怀疑(2),因为它似乎可能有用, while(1) 似乎没用。 (2) 基本上允许为可以支持的情况定义方法,而不将类型类限制为仅针对这些情况进行实例化。
这个例子似乎正是激发了这一点——这个想法是
elem
对于序列来说通常是一个有用的操作,没有它就太有值(value)了,但我们也希望支持那些 elem
的序列。是不支持的,例如函数序列。我是对的,还是我错过了什么?这个扩展的语义是什么?
最佳答案
注意:好像是 there is a bug in GHC >= 7这使得 GHC 即使在 Haskell 98 模式下也接受约束类方法。
此外,手册中的示例总是在 MultiParamTypeClasses
时被接受。已启用,无论 ConstrainedMethodTypes
是否扩展已打开(也可能是一个错误)。
类型为elem
:
elem :: Eq a => a -> s a -> Bool
a
和 s
是类类型变量,Eq a
是对类类型变量 a
的约束.正如手册所说,Haskell 98 禁止此类约束(FWIW,它也禁止多参数类型类)。因此,在 Haskell 98 模式下不应接受以下代码(我认为在 Haskell 2010 中也禁止使用):class Compare a where
comp :: Eq a => a -> a -> Bool
事实上,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.
这个想法是应该使用父类(super class)约束:
class (Eq a) => Compare a where
comp :: a -> a -> Bool
关于语义,您可以使用以下代码轻松检查类方法约束是否隐式添加父类(super class)约束:
{-# 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
使用 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
答案:不,它没有。约束仅适用于具有约束类型的方法。所以你是对的,这是可能性 #2。
关于haskell - GHC 扩展的语义允许对方法进行限制 (-XConstrainedClassMethods),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16139454/