我有2种类型,Tree和BinTree。我实现比较的方式是这样的:

instance (Eq a) => Ord (Tree a) where
  t <= u = traces t `subseteq` traces u

instance (Eq a) => Eq (Tree a) where
  t == u = traces t `subseteq` traces u && traces u `subseteq` traces t

instance (Eq a) => Ord (BinTree a) where
  t <= u = traces t `subseteq` traces u

instance (Eq a) => Eq (BinTree a) where
  t == u = traces t `subseteq` traces u && traces u `subseteq` traces t


如您所见,我的traces函数很乐意同时在Tree和BinTree上运行,因此应该有一种方法可以执行:
myBinTree
因此将BinTree与树进行比较

由于BinTree是Tree的子集,因此如何实现此功能以便可以比较BinTree和Trees。

最佳答案

不能以这种方式成为EqOrd类的实例。这些类具有签名:

(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool


等等...

您可以编写自己的(==)函数,但是该函数变得模棱两可,因此,您始终需要指定您实际上在谈论哪个(==)运算符。

您的评论“ haskell如何比较浮点数到整数?”的答案。是的,不是。如果您写:

> (1 :: Int) == (1.0 :: Float)

<interactive>:56:16:
    Couldn't match expected type `Int' with actual type `Float'
    In the second argument of `(==)', namely `(1.0 :: Float)'
    In the expression: (1 :: Int) == (1.0 :: Float)
    In an equation for `it': it = (1 :: Int) == (1.0 :: Float)


您会发现无法进行比较。您可以通过转换来做到这一点:

> fromIntegral (1 :: Int) == (1.0 :: Float)
True


其中fromIntegral是将Int转换为-在这种情况下为Float的函数。您可以通过实现bin2tree函数来执行相同的操作。

您当然可以定义自己的相似类:

class Similar a b where
    (=~) :: a -> b -> Bool
    (/=~) :: a -> b -> Bool
    (/=~) x y = not $ x =~ y


(并在文件中添加{-# LANGUAGE MultiParamTypeClasses #-}作为修饰符)。

然后例如:

instance (Similar a b) => Similar [a] [b] where
    (=~) [] [] = True
    (=~) _  [] = False
    (=~) [] _  = True
    (=~) (x:xs) (y:ys) = (x =~ y) && (xs =~ ys)


但是问题是,您必须自己重新定义许多方法(使用像Eq这样的nub),以便它们可以与您的Similar类一起使用。

08-07 23:59