Ingdas
Ingdas

Reputation: 1486

Set of an Unordered Data Type with a given ordering

I'm trying to put this data type in a Haskell Set, but I don't want to give it a general instance of Ord. So I want to give the set an ordering on y-coördinate but without instance Ord Vector. Is this possible?

    data Vector = V 
    { x :: Double
    , y :: Double
    } deriving (Eq)

Upvotes: 3

Views: 726

Answers (3)

yatima2975
yatima2975

Reputation: 6610

I've made a version of the Set datatype which does not have the Ord context, but instead needs a function of type a -> a -> Ordering passed in wherever a Set is constructed. Could that be useful in your case?

(I'm not sure about the copyright status, it's largely untested and the documentation is not modified, so I'm not just putting it up here...)

Upvotes: 0

Martijn
Martijn

Reputation: 6773

Set requires you to use the default Ord instance of the element type.

If you want to use a different Ord instance, the standard way to do that is to use a custom newtype wrapper and then write an Ord instance for that:

newtype Y = Y { unY :: Vector } deriving Eq
instance Ord Y where compare = comparing ((y . unY) &&& (x . unY))

But since this way of comparing is equivalent to the way binary tuples are compared, KennyTM's solution is the simplest here.

Upvotes: 8

kennytm
kennytm

Reputation: 523534

You can convert the vector into a tuple:

toTuple :: Vector -> (Double, Double)
toTuple (V x y) = (y, x)

fromTuple :: (Double, Double) -> Vector
fromTuple (y, x) = V x y

Since tuples derive Ord (using lexicographic comparison), they can be inserted to the Set. (Define 2 other functions for x-major ordering.)

Upvotes: 4

Related Questions