2013-03-21 12 views
7

Qualcuno può spiegarmi come si può ordi- nare un tipo di dati personalizzato ord -abile?Creazione di un tipo di dati personalizzato ord -abile

** Non sono autorizzato ad apportare modifiche a Suit stesso, ad es. derivante (Eq, Ord)

data Suit = Clubs | Diamonds | Hearts | Spades deriving (Eq) 

Il mio tentativo:

instance Ord Suit where 
    compare suit1 suit2 = compare suit1 suit2 

ma che sembra andare su un ciclo continuo e non si ferma.

+0

Bene, è necessario specificare in che modo questo deve essere confrontato. Non sono a conoscenza di alcun modo universale per decidere se Hearts è maggiore di Clubs. Quindi puoi utilizzare la corrispondenza del modello. – jozefg

+0

In realtà non ho bisogno di loro in un ordine specifico, ho solo bisogno che siano disposti l'uno accanto all'altro. – rlhh

+0

Siamo spiacenti? Quindi, in pratica, devi semplicemente scegliere un ordinamento arbitrario? – jozefg

risposta

8

La definizione di Ord sembra qualcosa di simile (ma non del tutto)

class Ord a where 
    compare :: a -> a -> Ordering 

e Ordering ha tre possibili valori: LT, EQ, GT.

Quindi, è necessario definire quale dovrebbe essere il risultato di ciascun confronto. Qualcosa del tipo:

instance Ord Suit where 
    compare Clubs Diamonds = LT 
    compare Diamonds Clubs = GT 
    compare Diamonds Diamonds = EQ 
    compare Diamonds _  = LT -- Diamonds are lower than everything besides Clubs and Diamonds 

Il tuo ordine effettivo potrebbe essere diverso, ma questo dovrebbe darti l'idea di base.

+0

Esiste comunque la possibilità di utilizzare l'ordinamento predefinito delle stringhe per ottenere qualcosa di simile? (Considerando che sto facendo più di un raggruppamento che di ordinamento) – rlhh

+0

Potrebbe definirlo come un'istanza di show e poi fare semplicemente 'compare = su compare show' – jozefg

+0

@jozefg È già dichiarato come un'istanza di Show, ma come farei effettivamente corretto il codice in Haskell? Esempio: 'show Clubs =" C "' – rlhh

3

Un modo per scrivere un campione personalizzato Ord in cui non c'è bisogno di precisare il risultato di ogni confronto è:

instance Ord Suit where 
    compare a b = compare (relativeRank a) (relativeRank b) where 
     relativeRank Diamonds = 1 
     relativeRank Clubs = 2 
     relativeRank Hearts = 3 
     relativeRank Spades = 4 

Qui, avete solo bisogno di parlare di ogni costruttore, una volta, e si può facilmente decidere su un diverso ordine.

Si può anche usare compare Data.Function.on relativeRank, ma questo è forse più facile da capire.

4

È possibile utilizzare standalone deriving con lo stesso effetto.

deriving instance Enum Suit 
deriving instance Ord Suit 
Problemi correlati