2010-05-07 1 views
9

Come può essere fatto nel modo più semplice per scrivere (o forse c'è qualcosa di incorporato nella funzione haskell) che accetta come lista di argomenti di tuple (String, Int) e Int x e restituisce tuple in cima x come lista secondo al valore x.ordinamento haskell

Mi chiedo se è possibile scrivere una funzione che accetta anche 3 argomenti che è il nome (o indice) di una tupla in base a quale ordinamento deve essere fatto.

Quali sono le migliori soluzioni per renderlo abbastanza generico?

+0

So che la tua domanda è probabilmente più per la tua curiosità, ma cosa stai facendo con i dati? Una lista ordinata è davvero ciò che vuoi ottenere? Non stiamo più spostando gli elementi negli array di basso livello nel paese C e haskell ti offre un facile accesso a un intero zoo di tipi di dati interessanti che probabilmente sono più appropriati per fare qualsiasi cosa tu stia facendo con i "ordinati" dati. – jberryman

+0

La ragione è che sto imparando e voglio sapere quali sono le possibilità, e la funzione di ordinamento è quella che tutti comprendono, quindi l'esplorazione è più facile. Naturalmente so di tipi embedded, ancora in fase di apprendimento, grazie – gruber

risposta

22
take x $ sortBy (compare `on` fst) [("asd", 1), ...] 

take x prende le prime x voci dall'elenco ordinato. sortBy ordina l'elenco indicato come secondo argomento utilizzando la funzione di ordinamento fornita come primo argomento. (compare `on` fst) confronta i primi valori di ciascuna tupla. Si noti che questo esempio confronta il primo valore di ogni tupla per l'ordinamento. Per ordinare in base al secondo valore, sostituire fst con snd.

Si vede che la funzione sortBy è molto generica, in quanto consente di definire la funzione utilizzata per confrontare i valori. La funzione accetta due argomenti e dovrebbe restituire uno di LT, EQ o GT. Si noti che la funzione compare richiede che entrambi gli argomenti derivino da Ord. La funzione helper on può essere trovata nel modulo Data.Function. La funzione sortBy si trova nel modulo Data.List.

MODIFICA: Ecco un esempio operativo completo che ordina un elenco di tuple confrontando i loro primi valori e stampa le prime 2 tuple dell'elenco risultante. Si noti che ho sostituito il on dell'esempio precedente con una funzione equivalente che mostra cosa fa internamente lo on.

import Data.Function 
import Data.List 

main = print $ mySort [("foo", 1), ("bar", 2), ("baz", 3), ("quux", 4)] 2 

mySort list x = take x $ sortBy (\ x y -> compare (fst x) (fst y)) list 

EDIT: Come Tom Lokhorst ha sottolineato nel suo commento, la funzione comparing dal modulo Data.Ord è un sostituto/scorciatoia più leggibile per on compare, in modo quanto sopra può anche essere scritta come sortBy (comparing fst).

+8

Si noti che la funzione 'comparing' di' Data.Ord' è la stessa di 'su compare'. Quindi potresti anche scrivere la lista 'sortBy (comparando fst)'. –

+0

Bello, non lo sapevo. – jkramer

+0

Se non dovessi "prendere" prima di 'sortBy'? mySort può potenzialmente prendere una lista infinita. –