我什么时候应该按类型 类 或其他方式定义多态函数?
When shall I define polymorphic functions by type classes or by some other ways?
我想弄清楚类型 class 的用途,如果不使用类型 class 还有什么?
类型class是一种定义多态函数的方法吗?
类型class是定义多态函数的唯一方法吗?例如:
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
instance Eq Bool where
False == False = True
True == True = True
_ == _ = False
我可以在不使用类型 class Eq
的情况下为 Bool
(和任何其他类型)定义 ==
和 /=
吗?
如果有其他方式,我什么时候应该使用哪种方式来定义多态函数,使用类型 class 还是使用其他方式?
OOP 中的多态函数与 haskell 中的多态函数之间存在差异,我之所以这样说是因为 OOP 中通常使用术语 "polymorphism "。
例如,列表上的函数是多态的:
cons:: a -> [a] -> [a]
cons x xs = x:xs
其中 a 是多态类型,那里没有类型类。
顺便说一句,有一种方法可以快速实现类型类,默认情况下,例如Eq
或Show
,例如:
data MBool = MTrue | MFalse deriving (Eq, Show)
所以,不同之处在于类型类是一个约束,想象一下这个带有列表的函数:
mapShow :: Show a => [a] -> [String]
mapShow = map show
不一样了,因为现在a是有限制的,不能是任何"a"。它应该实现类型类 Show
.
总而言之,您可以看到 cons
函数中的 a
类型比 mapShow
函数中的 Show => a -> a
类型更通用或更抽象。
Is type class a way to define polymorphic functions?
是,就是一个的方式。但不是唯一的方法。例如 参数多态性 只是意味着如果你定义一个像 init :: [a] -> [a]
这样的函数,它将适用于任何 a
。类型 类 用于 ad-hoc 多态性 :根据类型,实现可能完全不同。这与 参数多态性 形成对比,其中 head
函数始终相同,无论 a
.
的类型如何
Is type class the only way to define polymorphic functions?
否,见上一节
Can I define ==
and /=
for Bool
(and any other type) without using type class Eq
?
这取决于所有类型的实现是否相同。您可以使用 -XNoImplicitPrelude
标志来避免导入 Prelude
,然后您可以定义自己的 (==)
函数。
您始终可以编写 无约束 多态函数,不需要任何类型class。一个简单的例子是
length :: [a] -> Int
– 这在没有类型class 的情况下有效,并且(好吧,因为)它适用于任何类型 a
随便。也就是说,length
实际上并不关心列表中的 values 是什么,它只关心那些值所在的 structure包含。它实际上从不对这些值本身做任何事情,多态类型实际上保证了这一点。
如果您需要的多态任务是这种形式,即您实际上不需要访问的类型,您只知道它就在那里,那么您不应该write/invoke一个类型class,就像length
一样使用ML-style参数多态。但是,您经常 将 需要自己访问这些值,以某种方式检查它们。这样做而不将您限制为特定的具体类型是类型 classes 的用途。 Eq
,正如你自己引用的那样,就是一个例子。
我想弄清楚类型 class 的用途,如果不使用类型 class 还有什么?
类型class是一种定义多态函数的方法吗?
类型class是定义多态函数的唯一方法吗?例如:
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
instance Eq Bool where
False == False = True
True == True = True
_ == _ = False
我可以在不使用类型 class Eq
的情况下为 Bool
(和任何其他类型)定义 ==
和 /=
吗?
如果有其他方式,我什么时候应该使用哪种方式来定义多态函数,使用类型 class 还是使用其他方式?
OOP 中的多态函数与 haskell 中的多态函数之间存在差异,我之所以这样说是因为 OOP 中通常使用术语 "polymorphism "。
例如,列表上的函数是多态的:
cons:: a -> [a] -> [a]
cons x xs = x:xs
其中 a 是多态类型,那里没有类型类。
顺便说一句,有一种方法可以快速实现类型类,默认情况下,例如Eq
或Show
,例如:
data MBool = MTrue | MFalse deriving (Eq, Show)
所以,不同之处在于类型类是一个约束,想象一下这个带有列表的函数:
mapShow :: Show a => [a] -> [String]
mapShow = map show
不一样了,因为现在a是有限制的,不能是任何"a"。它应该实现类型类 Show
.
总而言之,您可以看到 cons
函数中的 a
类型比 mapShow
函数中的 Show => a -> a
类型更通用或更抽象。
Is type class a way to define polymorphic functions?
是,就是一个的方式。但不是唯一的方法。例如 参数多态性 只是意味着如果你定义一个像 init :: [a] -> [a]
这样的函数,它将适用于任何 a
。类型 类 用于 ad-hoc 多态性 :根据类型,实现可能完全不同。这与 参数多态性 形成对比,其中 head
函数始终相同,无论 a
.
Is type class the only way to define polymorphic functions?
否,见上一节
Can I define
==
and/=
forBool
(and any other type) without using type classEq
?
这取决于所有类型的实现是否相同。您可以使用 -XNoImplicitPrelude
标志来避免导入 Prelude
,然后您可以定义自己的 (==)
函数。
您始终可以编写 无约束 多态函数,不需要任何类型class。一个简单的例子是
length :: [a] -> Int
– 这在没有类型class 的情况下有效,并且(好吧,因为)它适用于任何类型 a
随便。也就是说,length
实际上并不关心列表中的 values 是什么,它只关心那些值所在的 structure包含。它实际上从不对这些值本身做任何事情,多态类型实际上保证了这一点。
如果您需要的多态任务是这种形式,即您实际上不需要访问的类型,您只知道它就在那里,那么您不应该write/invoke一个类型class,就像length
一样使用ML-style参数多态。但是,您经常 将 需要自己访问这些值,以某种方式检查它们。这样做而不将您限制为特定的具体类型是类型 classes 的用途。 Eq
,正如你自己引用的那样,就是一个例子。