比较 2 个相似类型?

Comparing 2 Similar Types?

我有两种类型,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 < myTree

因此将 BinTree 与 Tree 进行比较

如何实现这一点,以便可以比较 BinTrees 和 Trees,因为 BinTree 是 Tree 的子集。

不是以成为 Eq or Ord classes 的实例的方式。这些 classes 具有签名:

(==) :: 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:

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 class.