是否可以根据实现的类型类定义泛型类型的不同行为?

时间:2014-08-04 00:09:00

标签: haskell

实际上我想要提出一个额外的层,但措辞有点尴尬。以下是使用“了解你的Haskell”中的YesNo类型类的示例。

class YesNo a where
    yesno :: a -> Bool

instance YesNo Bool where
    yesno = id

instance YesNo [a] where
    yesno lst = length lst > 0

此处,泛型类型为[a]。是否可以更改此代码,以便yesnoFalse实施a时使用不同的逻辑(例如,返回YesNo)?

1 个答案:

答案 0 :(得分:10)

当您需要类型类基于包含的元素执行不同的操作时,典型的,通常是最好的事情是实际创建一个newtype包装器并手动将列表包装在调用站点。

newtype声明如下:

newtype AllOf a = AllOf { unAllOf :: [a] }

newtype AnyOf a = AnyOf { unAnyOf :: [a] }

并且,毫不奇怪,实例在基础列表中使用allany

instance YesNo a => YesNo (AllOf a) where
    yesno = all yesno . unAllOf


instance YesNo a => YesNo (AnyOf a) where
    yesno = any yesno . unAnyOf

然后当你想使用实例时:

*Main> yesno (AllOf [True, True, False, True])
False
*Main> yesno (AnyOf [True, True, False, True])
True