views:

114

answers:

2

I am attempting to make some data structures to solve a graph puzzle. I am trying to define an edge's comparison criteria, but I am not sure how. So far:

data Edge = Edge (Set String) Bool

How do I tell let the compiler know that I want edges to be declared equal if they have identical sets of strings, and not have equality have anything to do with the boolean value?

+5  A: 
import Data.Set

data Edge = Edge (Set String) Bool deriving Show

instance Eq Edge where
    (Edge a _) == (Edge b _) = a == b

instance Ord Edge where
    compare (Edge a _) (Edge b _) = compare a b
TomMD
+8  A: 

Although I'm not sure why you want to ignore the boolean value (I'm curious), to do so you'll have to define your own Eq instance; the default one won't work, as it compares every field. Luckily, this is easy:

instance Eq Edge where
  (Edge s1 _) == (Edge s2 _) = s1 == s2

If you want to be able to order edges, and you want the ordering to compare just the sets too, your implementation is very similar:

instance Ord Edge where
  (Edge s1 _) `compare` (Edge s2 _) = s1 `compare` s2

Each type class defines a certain set of methods which need to be implemented; Eq requires == or /=, and Ord requires <= or compare. (To find out which functions are required and which are optional, you can check the docs.)

Antal S-Z
I am ignoring the boolean because I am working with a directed graph. However, because the only edges that are important to me are ones that are are bidirectional between both nodes. I am using the boolean as a "reciprocated" field, so I can get rid of any directed edges that don't have an equivalent returning edge. I can then filter on that boolean to create an undirected graph.It's ugly but I can't think of anything else on short notice.
mvid