Haskell 使用typeclass实例时自动识别类型?
我将介绍一些基本的typeclass实现:Haskell 使用typeclass实例时自动识别类型?,haskell,typeclass,Haskell,Typeclass,我将介绍一些基本的typeclass实现: data Colour = Red | Green | Black class BasicEquality a where isEqual :: a -> a -> Bool instance BasicEquality Bool where isEqual True True = True isEqual False True = True isEqual True False = True isE
data Colour = Red | Green | Black
class BasicEquality a where
isEqual :: a -> a -> Bool
instance BasicEquality Bool where
isEqual True True = True
isEqual False True = True
isEqual True False = True
isEqual _ _ = False
instance BasicEquality Colour where
isEqual Red Green = True
isEqual _ _ = False
instance BasicEquality Int where
isEqual 100 100 = True
isEqual _ _ = False
main = do
print $ isEqual Red Green //Output: True
print $ isEqual 100 100 //Output: Error Ambiguous type variable ‘a0’ arising from a use of ‘isEqual’
显然,当我指定print$isEqual(100::Int)(100::Int)
为什么Haskell隐式地认识到Red
和Green
是colors
但需要我将100
绑定到Int
?Red
等是单形态值,即它们具有具体类型
Red :: Colour
因此,当Red
出现在您的代码中时,编译器立即知道它是什么类型,并且可以使用此信息推断要用于什么类型的typeclass实例,例如BasicEquality
OTOH,像100
这样的数字文本具有多态类型numa=>a
。原因是我们希望能够写作
Prelude> replicate 3 'q'
"qqq"
以及
Prelude> sqrt 3
1.7320508075688772
如果3
仅具有类型Int
,则后者将不起作用,因为sqrt
需要一种类型,例如Double
。因为数字文字实际上是多态的,所以这并不重要
您案例中的问题是,isEqual
也是多态的。因此,编译器可以选择多种不同的类型。你也有这样的形象
instance BasicEquality Integer where
isEqual 50 1000 = True
isEqual _ _ = False
然后isEqual 100 100
可以解释为isEqual(100::Int)100
(即True
)或isEqual(100::Integer)100
(即false)
在实践中,这很少是一个问题,因为您不会比较不同的数字文字(这些文字已经知道,所以您可以简单地对结果进行硬编码!),但在您的程序中最多一个文字和一个变量,并且该变量通常已经具有根据上下文确定的类型。比如说,
*Main> let b = length "foobar"
*Main> isEqual 4 b
False
没有任何签名的作品。Red
等为单态值,即它们具有具体类型
Red :: Colour
因此,当Red
出现在您的代码中时,编译器立即知道它是什么类型,并且可以使用此信息推断要用于什么类型的typeclass实例,例如BasicEquality
OTOH,像100
这样的数字文本具有多态类型numa=>a
。原因是我们希望能够写作
Prelude> replicate 3 'q'
"qqq"
以及
Prelude> sqrt 3
1.7320508075688772
如果3
仅具有类型Int
,则后者将不起作用,因为sqrt
需要一种类型,例如Double
。因为数字文字实际上是多态的,所以这并不重要
您案例中的问题是,isEqual
也是多态的。因此,编译器可以选择多种不同的类型。你也有这样的形象
instance BasicEquality Integer where
isEqual 50 1000 = True
isEqual _ _ = False
然后isEqual 100 100
可以解释为isEqual(100::Int)100
(即True
)或isEqual(100::Integer)100
(即false)
在实践中,这很少是一个问题,因为您不会比较不同的数字文字(这些文字已经知道,所以您可以简单地对结果进行硬编码!),但在您的程序中最多一个文字和一个变量,并且该变量通常已经具有根据上下文确定的类型。比如说,
*Main> let b = length "foobar"
*Main> isEqual 4 b
False
作品没有任何签名。“基本平等”是一种非常奇怪的平等形式。“基本平等”是一种非常奇怪的平等形式。