Reputation: 1116
I'd like to sort a list of two different types. To do so I first create a Wrapper
type, so I can mappend
both types.
Wrapper
type the right way here?fooDelta
and barDelta
)The code:
import Data.List (sortBy)
import Data.Monoid
import Data.Ord (comparing)
data Foo = Foo
{ fooLabel :: String
, fooDelta :: Int
} deriving (Show, Eq)
data Bar = Bar
{ barLabel :: String
, barDelta :: Int
, barAnother :: String
} deriving (Show, Eq)
data Wrapper = WFoo Foo | WBar Bar
deriving (Show, Eq)
sortTest :: [Wrapper]
sortTest =
listFoo <> listBar
where
listFoo = [WFoo $ Foo "label1" 0, WFoo $ Foo "label2" 2]
listBar = [WBar $ Bar "label1" 1 "another1"]
Upvotes: 1
Views: 248
Reputation: 2703
A wrapper type is definitely a good way to do this. Since you simply want to sort your wrapped values based on a constituent Int
value, you can use Data.List.sortOn
.
Define a function which extracts the delta value:
delta :: Wrapper -> Int
delta (WFoo f) = fooDelta f
delta (WBar b) = barDelta b
Then use sortOn
like this:
main :: IO ()
main = print $ sortOn delta sortTest
This gives the following output for your example:
[WFoo (Foo {fooLabel = "label1", fooDelta = 0}),WBar (Bar {barLabel = "label1", barDelta = 1, barAnother = "another1"}),WFoo (Foo {fooLabel = "label2", fooDelta = 2})]
Another way to do this is to define an Ord
instance for your wrapper type. Then you can simply use sort
on your [Wrapper]
list.
Upvotes: 2