2010-07-25 13 views
16

Sto cambiando alcuni codici Haskell dall'utilizzo di elenchi a insiemi. Capisco tutto ciò che è necessario, penso, ma non sono sicuro di come abbinare il pattern sui set. Le liste hanno questa bella sintassi letterale che sembra difficile da emulare con il costruttore Set. Ad esempio, potrei avere qualche codice come questo:Corrispondenza pattern Haskell sul set vuoto

foo [] = [] 
foo x = other_thing 

Come faccio a scrivere questo codice in modo che utilizza set al posto delle liste?

risposta

30

Bene, non è possibile.

Set è un tipo astratto[0] che nasconde deliberatamente la sua rappresentazione interna, soprattutto per mantenere invarianti della struttura dati che non possono essere staticamente-imposto dal sistema tipo (specificamente, la libreria standard Data.Set.Set è un albero di ricerca binario).

Perdere la possibilità di associare il modello a un tipo di dati astratto è un po 'spiacevole di danno collaterale, ma vabbè. Le tue opzioni sono approssimativamente:

  • Utilizzare predicati e guardie booleani, ad es. null, come nella risposta di trinithis.
  • Convertire il Set in un elenco. La maggior parte delle volte questo è sciocco, ma se vuoi scorrere l'insieme comunque, funziona abbastanza bene.
  • Abilita GHC's ViewPatterns extension, che fornisce zucchero sintattico per l'utilizzo delle funzioni di accesso dove normalmente si verifica una corrispondenza di modello.
  • Evitare di fare questo tipo di controlli in primo luogo - se si dispone di un Set, trattarlo come un set, e lavorare con esso nel suo complesso per la mappatura, il filtro, ecc. Non sempre possibile, ma può portare per un codice più pulito con meno condizionali/iterazioni esplicite.

Visualizza modelli lascerebbero si scrive qualcosa che assomiglia a questo:

foo (setView -> EmptySet) = [] 
foo (setView -> NonEmpty set) = other_thing 

... dove setView è una funzione che si scrive. Non c'è molto di un guadagno qui, ma può essere piacevole per maggiori complessi pseudo-modelli

Per evitare controlli espliciti, oltre ben note operazioni di set, come union e intersection, considerano facendo uso del filter, partition, map, e fold funzioni in Data.Set.

[0]: Vedere this paper (avviso: PDF) per la definizione del termine come lo sto usando.

+0

+1 per il riferimento ViewPatterns! – ShiDoiSi

29
import qualified Data.Set as Set 

foo set 
    | Set.null set = bar 
    | otherwise = baz 
+1

+1 per risposta semplice –

+7

@simonjpascoe: Aspetta, possiamo dare * semplici * risposte? E qui per tutto questo tempo ho pensato che ci fosse un minimo di tre paragrafi ... –

Problemi correlati