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

Zan*_*ier 5 haskell

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

class YesNo a where
    yesno :: a -> Bool

instance YesNo Bool where
    yesno = id

instance YesNo [a] where
    yesno lst = length lst > 0
Run Code Online (Sandbox Code Playgroud)

这里,泛型类型是[a].是否可以更改此代码,以便在实现时yesno使用不同的逻辑(例如返回False)?aYesNo

Tho*_*son 10

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

newtype声明如下所示:

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

newtype AnyOf a = AnyOf { unAnyOf :: [a] }
Run Code Online (Sandbox Code Playgroud)

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

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


instance YesNo a => YesNo (AnyOf a) where
    yesno = any yesno . unAnyOf
Run Code Online (Sandbox Code Playgroud)

然后当你想使用实例时:

*Main> yesno (AllOf [True, True, False, True])
False
*Main> yesno (AnyOf [True, True, False, True])
True
Run Code Online (Sandbox Code Playgroud)