Suppose I have
data Foo = A String Int | B Int
I want to take an xs :: [Foo] and sort it such that all the As are at the beginning, sorted by their strings, but with the ints in the order they appeared in the list, and then have all the Bs at the end, in the same order they appeared.
In particular, I want to create a new list containg the first A of each string and the first B.
I did this by defining a function taking Foos to (Int, String)s and using sortBy and groupBy.
Is there a cleaner way to do this? Preferably one that generalizes to at least 10 constructors.
Typeable, maybe? Something else that’s nicer?
EDIT: This is used for processing a list of Foos that is used elsewhere. There is already an Ord instance which is the normal ordering.
You can use
where
foois a function that extracts the interesting parts into something comparable (e.g.Ints).In the example, since you want the
As sorted by theirStrings, a mapping toIntwith the desired properties would be too complicated, so we use a compound target type.would be a possible helper. This is more or less equivalent to Tikhon Jelvis’ suggestion, but it leaves space for the natural
Ordinstance.