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 Vecto开发者_C百科r. Is this possible?
data Vector = V
{ x :: Double
, y :: Double
} deriving (Eq)
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.
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.)
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...)
精彩评论