我必须定义一个类型类Truthy
其中包含一个方法true
将类型类的实例转换为Bool
value.
我的类型类声明:
class Truthy a where
true :: a -> Bool
接下来,我必须为各种类型定义此类的实例,包括列表和数字类型。我已经为列表完成了它Int
s,但是有没有办法同时对所有数字类型执行此操作?
根据我的 Int 声明:
instance Truthy Int where
true = (/=) 0
我尝试添加类型类约束,但它不起作用:
instance (Num a) => (Truthy a) where
true = (/=) 0::a
是否有一种方法可以做到与我的想法类似,或者我应该为每个数字类型单独定义它?
这可能对家庭作业没有帮助,但实际上can写一个这样的声明。您只需启用-XFlexibleInstances
这样做。至少在 GHC 中,您可以通过在文件顶部放置一个编译指示来做到这一点:
{-# LANGUAGE FlexibleInstances #-}
如果您仔细查看收到的错误消息,它会显示类似“如果您想禁用此功能,请使用 -XFlexibleInstances”之类的内容。
在这种特殊情况下,您还需要启用UndecidableInstances
and OverlappingInstances
:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
你需要FlexibleInstances
因为标准 Haskell 不允许任何形式的实例,其中类型变量在头部出现多次。这完全没问题——它是最常用的扩展之一(根据这个问题 https://stackoverflow.com/questions/4826630/type-class-problem-concerning-flexibleinstances).
你需要UndecidableInstances
因为您的实例声明可能会导致类型检查器永远循环。我认为使用UndecidableInstances
通过限制尝试减少实例时检查的深度来防止这种情况发生。这通常(包括在这种情况下)很好,但理论上可以确定特定程序是否通过类型检查依赖于实现。不过,它应该适用于你的情况。
正如哈马尔指出的那样,您需要启用OverlappingInstances
因为实例的“上下文”是ignored检查它们是否重叠时。上下文是Num a
在这种情况下有点。因此,用于检查是否重叠的实例被读作instance Truthy a...
并与一切重叠。和OverlappingInstances
启用后,您只需要拥有一个最具体的实例即可使其工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)