实际上我想要提出一个额外的层,但措辞有点尴尬。以下是使用“了解你的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]
。是否可以更改此代码,以便yesno
在False
实施a
时使用不同的逻辑(例如,返回YesNo
)?
答案 0 :(得分:10)
当您需要类型类基于包含的元素执行不同的操作时,典型的,通常是最好的事情是实际创建一个newtype包装器并手动将列表包装在调用站点。
newtype声明如下:
newtype AllOf a = AllOf { unAllOf :: [a] }
newtype AnyOf a = AnyOf { unAnyOf :: [a] }
并且,毫不奇怪,实例在基础列表中使用all
或any
:
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