我必须定义一个类型类,它Truthy包含一个true将类型类的实例转换为Bool值的方法.
我的类型类声明:
class Truthy a where
true :: a -> Bool
Run Code Online (Sandbox Code Playgroud)
接下来,我必须为各种类型定义此类的实例,包括列表和数字类型.我已经为list和Ints 做过了,但有没有办法一次为所有数字类型做到这一点?
基于我的Int声明:
instance Truthy Int where
true = (/=) 0
Run Code Online (Sandbox Code Playgroud)
我已经尝试添加类型类约束,但它不起作用:
instance (Num a) => (Truthy a) where
true = (/=) 0::a
Run Code Online (Sandbox Code Playgroud)
如果有一种方法与我的想法相似,或者我应该分别为每种数字类型定义它?
Tik*_*vis 10
这可能对家庭作业没有帮助,但你实际上可以写出这样的声明.你只需启用-XFlexibleInstances即可.至少在GHC中,您可以通过在文件顶部放置一个pragma来完成此操作:
{-# LANGUAGE FlexibleInstances #-}
Run Code Online (Sandbox Code Playgroud)
如果你仔细查看你得到的错误消息,它会说"如果你想禁用它,请使用-XFlexibleInstances.".
在这种特殊情况下,您还需要启用UndecidableInstances和OverlappingInstances:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
Run Code Online (Sandbox Code Playgroud)
您需要,FlexibleInstances因为标准Haskell不允许任何形式的实例,其中类型变量在头部中出现多次.这完全没问题 - 我是最常用的扩展之一(根据这个问题).
您需要,UndecidableInstances因为您的实例声明可能会导致类型检查器永远循环.我认为使用UndecidableInstances可以通过限制尝试减少实例时检查的深度来防止这种情况.这通常 - 包括在这种情况下 - 很好,但理论上可以使特定程序是否通过类型检查实现依赖.不过,它应该适用于你的情况.
正如hammar指出的那样,您需要启用,OverlappingInstances因为在检查实例是否重叠时会忽略实例的"上下文" .Num a在这种情况下,背景是有点的.因此,实例 - 用于检查它是否重叠 - 被读取instance Truthy a...并与所有内容重叠.与OverlappingInstances启用,你只需要有一个实例,它是最具体的这个工作.