2016-10-29 4 views
1

두 가지 유형의 목록을 정렬하고 싶습니다. 그렇게하려면 먼저 Wrapper 유형을 작성하십시오. 따라서 mappend 유형을 사용할 수 있습니다.다른 유형의 목록 정렬

  1. 여기에 Wrapper 유형이 있습니까? 내가 델타 키를 기준으로 정렬하려는 경우
  2. 은 내가 실제 정렬을 수행 할 방법에 대한 명확하지 않다 (즉, fooDeltabarDelta)

코드 :

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

요소에 대해 원하는 순서는 무엇입니까? – dkasak

+0

오 죄송합니다. 질문을 정렬 요구 사항으로 업데이트했습니다. – amitaibu

답변

2

래퍼 유형은 확실히이 작업을 수행하는 좋은 방법입니다. 구성 요소 Int 값을 기준으로 랩핑 된 값을 정렬하기 만하면되므로 Data.List.sortOn을 사용할 수 있습니다.

델타 값을 추출하는 함수를 정의한다 :

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 인스턴스를 정의하는 것입니다. 그런 다음 [Wrapper] 목록에 sort을 간단하게 사용할 수 있습니다.

+1

dkasak 귀하의 위대한 답변과 설명은 매우 감사드립니다. 하스켈을 더 친숙하게 해주셔서 감사합니다! – amitaibu

+0

대단히 환영합니다! – dkasak