1
我試圖實現一個排序的多屬性排序,適用於任何列表。Haskell:多屬性排序不夠通用
import Data.Ord (Ordering, Down (..), comparing)
import Data.List (sortBy)
import Data.Monoid (mconcat)
data Order a = ASC a | DESC a
orderBy :: Ord b => [Order (a -> b)] -> [a] -> [a]
orderBy rankedProperties unsorted =
sortBy rankedCompare unsorted
where
rankedCompare x y =
mconcat $ map
(\property ->
case property of
ASC f -> comparing f x y
DESC f -> comparing (Down . f) x y
) rankedProperties
它現在適用於元組和記錄,但是我發現了一個問題。問題是orderBy
中的b
必須相同。這是考慮這個問題:
data Row = Row { shortListed :: Bool, cost :: Float, distance1 :: Int, distance2 :: Int } deriving (Show, Eq)
我希望能夠說:orderBy [ASC shortListed, DESC cost] listofrows
。
但是回來的錯誤是:
<interactive>:1:31:
Couldn't match type ‘Float’ with ‘Bool’
Expected type: Row -> Bool
Actual type: Row -> Float
In the first argument of ‘ASC’, namely ‘cost’
In the expression: ASC cost
我需要一種方法來使b
型通用,爲b
只有真正必須由comparing
功能comparing :: Ord a => (b -> a) -> b -> b -> Ordering
接受。
我讀了一點關於存在類型和異構列表,但我不知道如何繼續。
我想的只是接受,能產生'Ordering'的功能,但我認爲它會產生太多的噪音與重複「比較」。然而,我沒有意識到只是將'比較'包裝到升序和降序構造函數中。 – CMCDragonkai