2010-07-25 5 views
16

Ich ändere etwas Haskell-Code von der Verwendung von Listen zu Sätzen. Ich verstehe alles Erforderliche, denke ich, aber ich bin mir nicht sicher, wie man Matches auf Sets mattieren kann. Listen haben diese nette literale Syntax, die mit dem Set-Konstruktor schwer zu emulieren scheint. Zum Beispiel könnte ich einige Code wie diese:Haskell-Muster, das auf das leere Set passt

foo [] = [] 
foo x = other_thing 

Wie kann ich diesen Code zu schreiben, so dass es Sets statt Listen verwendet?

Antwort

30

Nun, Sie können nicht.

Set ist ein abstrakter Datentyp [0] die absichtlich ihre interne Darstellung verbirgt, in erster Linie Invarianten der Datenstruktur zu erhalten, die nicht statisch durchgesetzt werden kann durch die Art System (genauer gesagt, die Standard-Bibliothek Data.Set.Set ist ein binärer Suchbaum).

Die Fähigkeit zu verlieren, einen abstrakten Datentyp zu pattern, ist ein unangenehmer Nebeneffekt, aber naja. Ihre Optionen sind grob:

  • Verwenden booleschen Prädikaten und Wachen, z. null, wie in Trinithis Antwort.
  • Konvertieren Sie die Set in eine Liste. Meistens ist das albern, aber wenn Sie trotzdem das Set durchlaufen wollen, funktioniert es gut genug.
  • Aktivieren Sie GHC's ViewPatterns extension, die syntaktischen Zucker für die Verwendung von Accessor-Funktionen bietet, wo eine Musterübereinstimmung normalerweise gehen würde.
  • Vermeiden Sie diese Art von Prüfungen an erster Stelle - wenn Sie eine Set haben, behandeln Sie es wie ein Set, und arbeiten Sie als Ganzes für die Zuordnung, Filterung, etc. Nicht immer möglich, aber kann führen zu sauberer Code mit weniger expliziten Bedingungen/Iterationen.

Ansicht Muster würden Sie etwas schreiben, das wie folgt aussieht:

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

... wo setView ist eine Funktion, die Sie schreiben. Nicht wirklich viel von einem Gewinn hier, kann aber für komplexere pseudo-Muster

Zur Vermeidung von expliziten Kontrollen neben bekannten Satz Operationen wie union und intersection, betrachten die Nutzung des filter, partition, map schön, und fold Funktionen in Data.Set.

[0]: Siehe this paper (Warnung: PDF) für die Definition des Begriffs, wie ich es bin mit.

+0

+1 für die ViewPatterns-Referenz! – ShiDoiSi

29
import qualified Data.Set as Set 

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

+1 für einfache Antwort –

+7

@simonjpascoe: Warten, können wir * einfache * Antworten geben? Und hier die ganze Zeit dachte ich, es gäbe ein Minimum von drei Paragraphen ... –

Verwandte Themen