排序不同类型的列表

时间:2016-10-29 16:40:45

标签: haskell

我想对两种不同类型的列表进行排序。为此,我首先创建Wrapper类型,因此我可以mappend两种类型。

  1. 这里有正确的Wrapper类型吗?
  2. 如果我想按delta键排序(即fooDeltabarDelta
  3. ,我不知道如何进行实际排序

    代码:

    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"]
    

1 个答案:

答案 0 :(得分:2)

包装类型绝对是一种很好的方法。由于您只想根据成分Int值对包装值进行排序,因此可以使用Data.List.sortOn

定义一个提取delta值的函数:

delta :: Wrapper -> Int
delta (WFoo f) = fooDelta f
delta (WBar b) = barDelta b

然后像这样使用sortOn

main :: IO ()
main = print $ sortOn delta sortTest

这为您的示例提供了以下输出:

[WFoo (Foo {fooLabel = "label1", fooDelta = 0}),WBar (Bar {barLabel = "label1", barDelta = 1, barAnother = "another1"}),WFoo (Foo {fooLabel = "label2", fooDelta = 2})]

另一种方法是为包装器类型定义Ord实例。然后,您只需在sort列表中使用[Wrapper]