2017-12-19 2 views

Antwort

8

Sie können fromListWith verwenden, etwa so:

import Data.Map 
groupByKey :: (Ord k) => (v -> k) -> [v] -> Map k [v] 
groupByKey getkey 
    = fromListWith (++) . fmap (\val -> (getkey val, [val])) 

so dass:

> groupByKey length $ words "hello there my good friend" 
fromList [(2,["my"]),(4,["good"]),(5,["there","hello"]),(6,["friend"])] 
> 
+0

Ich mag 'fromListWith' nicht, weil es zu schwer ist die Art und Weise der Kombination von Funktion zu erinnern wird angewandt. Ich würde lieber etwas wie '(a -> b) -> (a -> b -> b) -> [(k, a)] -> Map kb' sehen, aber selbst das muss die Reihenfolge angeben welche Listenelemente zur 'Map' hinzugefügt werden. Hm. Vielleicht haben Sie eine gute Idee, in diesem Fall kann ich es zu "Data.Map" hinzufügen. – dfeuer

+0

@dfeuer, eigentlich habe ich * eine Idee. Betrachte: 'fromFold :: (Ord k, Monoid m, Faltbares t) => t (k, m) -> Karte k m'. Durch die implizite Verwendung des assoziativen Monoid-Operators spielt es keine Rolle, welches Argument der Wert "eingefügt" wird - schließlich wird jeder Schlüssel dem "mconcat" der Liste der Werte für den Schlüssel zugeordnet (mit gleichen Werten wie die Eingabeliste). Fügen Sie 'fromFoldr :: (Ord k, faltbares t) => (a -> b -> b) -> b -> t (k, a) -> Map kb' (und' fromFoldl') hinzu, um explizite Monoid-Instanzen zu vermeiden und es sieht ziemlich gut aus. Vielleicht sollte ich etwas vorschlagen [email protected]? –

+0

Betrachten Sie den Leistungseinfluss von 'a ++ (b ++ c)' vs '(a ++ b) ++ c'. – dfeuer

Verwandte Themen