[英]Haskell Eq between different types
我需要使用此数据结构data D = C Int Float
并且需要将其与Int进行比较,例如a::D == 2
。
如何创建实例来定义这种Eq?
谢谢!
我将执行一个预测:
getInt :: D -> Int
getInt (C i _) = i
然后与之比较:
getInt myD == 5
您甚至可以将其包含在记录中:
data D = C { getInt :: Int, getFloat :: Float }
如果你喜欢
你不能 ==
具有签名a -> a -> Bool
,所以不能这样使用。
使用convertible
包,您可以定义
(~==) :: (Convertible a b, Eq b) => a -> b -> Bool
x ~== y = case safeConvert x of
Right x' -> x' == y
Left _ -> False
(==~) :: (Convertible b a, Eq a) => a -> b -> Bool
(==~) = flip (~==)
instance Convertible Int D where ...
-- or D Int depending on what you have in mind
不依赖于convertible
,你可以只定义转换功能无论是从Int
到D
(写a == fromInt 2
),反之亦然。
不推荐使用的路线(对于这种特定情况,我认为它比第一种解决方案更糟糕)是定义自己的类型类,例如
class Eq' a b where
(=~=) :: a -> b -> Bool
instance Eq a => Eq' a a where
x =~= y = x == y
instance Eq' D Int where ...
等等
可以这样做,但是我怀疑您会想要这样做。 正如Alexey提到的(==)
的类型是Eq a=>a->a->Bool
,因此进行此工作的唯一方法是使2
具有类型D
乍一看这似乎很荒谬,但实际上,可以使数字具有所需的任何类型,只要该类型是Num
的实例即可
instance Num D where
fromInteger x = C x 1.0
不过,仍有很多事情需要解决。
首先,您需要完全实现Num
所有功能,包括(+)
, (*)
, abs
, signum
, fromInteger
和(negate | (-))
。
啊!
其次,您需要从Integer中填写额外的Float
。 我选择了上面的值1.0
,但这是任意的。
第三,您还需要实际使D
成为Eq
的实例,以填写实际的(==)
。
instance Eq D where
(C x _) == (C y _) = x == y
请注意,这也是相当随意的,因为我需要忽略Float值以获取(==)
来执行所需的操作。
最重要的是,这可以做您想要的事情,但是会以滥用Num
类型和Eq
类型为代价。... Num
类型应该保留给您实际认为是数字,并且应该保留Eq
类型以比较两个完整的对象,每个对象都包括在内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.