Tim*_*Tim 3 polymorphism haskell typeclass adhoc-polymorphism
我试图弄清类型类的目的,如果不使用类型类,还有什么呢?
类型类是定义多态函数的一种方法吗?
类型类是定义多态函数的唯一方法吗?例如:
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
instance Eq Bool where
False == False = True
True == True = True
_ == _ = False
Run Code Online (Sandbox Code Playgroud)
我可以定义==和/=对Bool(以及任何其他类型),而无需使用类型的类Eq?
在有其他方法的地方,何时应该使用类型类或其他方法来定义多态函数?
您始终可以编写无约束的多态函数,该函数不需要任何类型类。一个简单的例子是
length :: [a] -> Int
Run Code Online (Sandbox Code Playgroud)
–这不需要类型类,并且(因为)它适用于任何类型 a。也就是说,length实际上并不在乎该列表中的值是什么,它仅在乎包含这些值的结构。实际上,它永远不会对这些值本身做任何事情,而多态类型实际上可以保证这一点。
如果您需要的多态任务是这种形式的,即实际上不需要访问的类型,而您只知道它在那里,那么您就不应该编写/调用类型类,只需使用ML样式的参数多态性即可,如length。但是,很多时候您将需要访问值本身,以某种方式对其进行检查。在不限制您使用特定具体类型的情况下做到这一点,就是要使用什么类型类。Eq如您所言,就是一个例子。
类型类是定义多态函数的一种方法吗?
是的,这是一种方法。但不是唯一的方法。例如,参数多态性只是意味着,如果您定义类似的函数init :: [a] -> [a],它将对任何函数都有效a。类型类用于临时多态性:根据类型,实现可以完全不同。这与参数多态性相反,在参数多态性中,head函数始终是相同的,而与的类型无关a。
类型类是定义多态函数的唯一方法吗?
不,请参见上一节。
我可以定义
==和/=对Bool(以及任何其他类型),而无需使用类型的类Eq?
这取决于所有类型的实现是否相同。您可以使用该-XNoImplicitPrelude标志来避免导入Prelude,然后可以定义自己的(==)函数。
OOP和haskell中的多态功能之间存在差异,我之所以这样说是因为OOP中通常使用术语“多态”。
例如,列表中的函数是多态的:
cons:: a -> [a] -> [a]
cons x xs = x:xs
Run Code Online (Sandbox Code Playgroud)
其中a是多态类型,那里没有类型类。
顺便说一句,默认情况下有一种方法可以快速实现类型类,例如Eq或Show,例如:
data MBool = MTrue | MFalse deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)
因此,区别在于类型类是一个约束,想象一下这个函数与列表:
mapShow :: Show a => [a] -> [String]
mapShow = map show
Run Code Online (Sandbox Code Playgroud)
这是不同的,因为现在a被限制了,它不能是任何“ a”。它应该实现typeclass Show。
总之,您可以看到函数a类型cons比函数Show => a -> a 类型更通用或更抽象mapShow。