私は、何かのリストで動作するランク付きのマルチプロパティソートを実装しようとしていました。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
が同じでなければならないということです。 orderBy [ASC shortListed, DESC cost] listofrows
:私が言うことができるようにしたい
data Row = Row { shortListed :: Bool, cost :: Float, distance1 :: Int, distance2 :: Int } deriving (Show, Eq)
:それはこのことを考慮しています。
れるが戻ってくるエラー:
<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
はだけは本当にcomparing
機能comparing :: Ord a => (b -> a) -> b -> b -> Ordering
で許容しなければならないので、私は、b
タイプが一般的なようにする方法が必要です。
私は実在のタイプと異種のリストについて少しは読んだことがありますが、どのように進むべきかわかりません。
私はちょうど 'Ordering'を作り出す機能を受け入れることを考えていたが、私はそれがあまりにも多くを作成するだろうと思いました反復的な「比較」を伴うノイズ。しかし、私は昇順と降順のコンストラクタに 'comparison'をラップするだけではわかりませんでした。 – CMCDragonkai