2

我有一个图表声明,我需要在 Haskell 中重载“==”运算符(书中的问题)。

data Node a = Node {
label :: a,
adjacent :: [(a,Int)]
} deriving Show

data Network a = Graph [Node a] deriving Show

基本上,如果两个图具有相同的顶点和边,则它们是相等的(但节点在网络数据类型中的顺序以及在节点数据类型中的相邻顶点列表可能不同)。有一些困难,任何帮助将不胜感激。

提前致谢。

注意:我的问题是相等性检查,而不是创建类型类实例的语法。

4

3 回答 3

6

如果你不能只使用deriving (Eq, Show),那么你必须手动实现它。

instance (Eq a) => Eq (Node a) where
    n1 == n2 = (* Implement the equality check here *)

instance (Eq a) => Eq (Network a) where
    g1 == g2 = (* Implement the equality check here *)

这实际上是派生语句自动为您所做的。

如果您想了解更多关于类型类的信息,我喜欢向您学习 Haskell 的解释。

如果您需要有关实际相等性检查的帮助,请使用Data.MapfromList函数。

至于节点,这个片段应该这样做

(==) = (==) `on` label

或更明确地说

n1 == n2 = label n1 == label n2
于 2013-04-23T15:47:13.193 回答
5

这是你要找的吗?

import Data.Function (on)
import qualified Data.Map as M

instance Ord a => Eq (Network a) where
    (==) = (==) `on` f where
        f :: Ord a => Network a -> M.Map a (M.Map a Int)
        f (Graph nodes) = M.fromList $ map g nodes
        g :: Ord a => Node a -> (a, M.Map a Int)
        g node = (label node, M.fromList $ adjacent node)

这个实现的作用:

  • 将每个网络转换为地图
  • 测试这些地图是否相等

因为地图是无序的(并且原始列表不包含重复项),原始列表的顺序不会影响输出。

您甚至可能会更好地将您的NodeNetwork表示更改为使用Maps。

于 2013-04-23T15:57:56.517 回答
0

您必须为网络实现 Eq 实例:

instance Eq (Network a) where
    n1 == n2 = ...

更多在这里:

http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101

https://en.wikibooks.org/wiki/Haskell/Classes_and_types

于 2013-04-23T15:47:00.690 回答