类型类,类似其他语言的接口,但是它用的关键字在 Haskell 是 class,类如 Eq 类型类是这样的,最好一行是表明,只实现 == 或者 /=,就可以了:
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x /= y)
x /= y = not (x == y)
{-# MINIMAL (==) | (/=) #-}
-- 类型类
data MuNum = O | Zero | One
-- 实现类型类,使用 instance 关键字
instance Eq MuNum where
O == Zero = True
O == One = True
Zero == Zero = True
One == One = True
_ == _ = False
单位半群类型类 Monoid
十二进制的钟表的时间及其加法运算可以理解为一个单位半群,集合 {1...12},运算符为 +,那么 12 是单位元,加上 12 小时后和当前的时间相同,很多数据类型可以抽象为单位半群,也就是说,他们都存在一个满足结合律的二元运算和一个单位元:
class Moniad a where
mempty :: a
mappend :: a -> a -> a
很多类型类,都为 Monoid 类型类的实例,例如 Bool, && 运算是满足结合律,True 是单位元。
半群类型类 Semigroup
如果单位半群没有单位元,这个代数结构就是半群,也就只有二元运算的集合。任意类型的列表是单位半群,也是半群。
Prelude> :m +Data.Semigroup
Prelude Data.Semigroup> [1,2,3] <> [4,5,6]
[1,2,3,4,5,6]