13 Stimmen

Haskell - sortBy-Funktion

Ich habe eine Liste von Vektoren. Nun möchte ich diese Liste von Vektoren nach ihrer Länge sortieren, indem ich die Funktion sortBy verwende. Was ich bereits habe, ist:

import Data.List

vectorLength::(Int,Int)->Float
vectorLength(x,y) = sqrt(fromIntegral ((x^2)+(y^2)))

sortVectors::[(Int, Int)]->[(Int, Int)]
sortVectors list = sortBy(map vectorLength list) list

main = do
    print(map vectorLength [(1,4), (2,6), (-2, -8), (3, -4)])
    print(sortVectors[(1,4), (2,6), (-2,-8), (3, -4)])

Die Funktion vectorLength funktioniert.

map vectorLength [(1,4), (2,6), (-2,-8),(3,-4)]   
output: [4.1231055, 6.3245554, 8.246211, 5.0]

Ich möchte beim Aufruf der folgenden Funktion

sortVectors [(1,4), (2,6), (-2,-8), (3,-4)]  
output: [(-2,-8), (2,6), (3,-4), (1,4)]

Aber ich erhalte die folgende Fehlermeldung:

Couldn't match expected type `(Int, Int)' with actual type `[a0]'
    Expected type: (Int, Int) -> (Int, Int) -> Ordering
      Actual type: [a0] -> [b0]
    In the return type of a call of `map'
    In the first argument of `sortBy', namely `(map vectorLength list)'
    In the expression: sortBy (map vectorLength list) list

Ich danke Ihnen für Ihre Hilfe. Hier ist meine Lösung

import Data.List

vectorLength::(Int,Int)->Float
vectorLength(x,y) = sqrt(fromIntegral ((x^2)+(y^2)))

sortVectors::[(Int, Int)]->[(Int, Int)]
sortVectors list = rever(sortBy compareVectors list)

rever::[(Int, Int)]->[(Int, Int)]
rever [] = []
rever (x:xs) = rever xs ++ [x]

compareVectors::(Int, Int) ->(Int, Int) ->Ordering
compareVectors(a,b) (c,d) 
    | vectorLength(a,b) < vectorLength(c,d) = LT
    | vectorLength(a,b) > vectorLength(c,d) = GT

main = do
    print(map vectorLength [(1,4), (2,6), (-2, -8), (3, -4)])
    print(sortVectors[(1,4), (2,6), (-2,-8), (3, -4)])

18voto

Ingo Punkte 35534

Sie schreiben einfach:

sortBy (comparing vectorLength) ....

Sie haben eine Liste als erstes Element für sortBy angegeben, aber eine Funktion ist erforderlich.

Um es auszuschreiben: Sie wollen es:

sortBy comparVectors listofvectors
    where comparVectors a b = vectorLength a `compare` vectorLength b

8voto

hugomg Punkte 65700

Die Perl-Leute nennen das folgende Muster die Schwartzsche_Transformation

Ändern Sie einfach Ihre Liste in eine Liste von Schlüssel-Wert-Paaren und sortieren Sie nach Schlüssel. (Dies vermeidet zusätzliche Berechnungen der Schlüsselfunktion, wenn diese teuer ist)

sortByKey keyf xs =
    let k_xs = map (\x-> (keyf x, x)) xs in
    let sorted = sortBy (compare `on` fst) k_xs in
    map snd sorted

sortByKey vectorLength vectors

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X