2013-12-21 2 views
5

In Haskell, habe ich ein Modul mit einem Teil Auftragsart:Kann eine benutzerdefinierte Musterzerlegung in Haskell bereitgestellt werden?

data PartialOrder a = PartialOrder [a] [(a, a)] 

ich denn das ist nicht, wie ich die Art verwendet werden soll ist nicht den Wert Konstruktor exportieren, aber ich will noch in der Lage sein Muster stimmen mit dem PartialOrder-Typ außerhalb des Moduls überein; Ist das möglich? Insbesondere möchte ich Muster Spiel etwas zu können, die nicht der Typ, Konstruktor, sondern stattdessen auf Mustererkennung etwas wie folgt aus:

f (PartialOrder xs le) = ... 

Wo le ist eine Funktion, die explizite Ordnung in die definierte implizit definieren Wertkonstruktor. Ich weiß, dass eine solche Einrichtung in Scala verfügbar ist, gibt es eine Möglichkeit, das Gleiche in Haskell zu tun?

Vielen Dank im Voraus.

Antwort

12

Es klingt wie ein Anwendungsfall für ViewPatterns. Sie könnten eine Art schreiben wie:

data ViewPartialOrder a = ViewPartialOrder a (a -> a -> Ordering) 

Schreiben Sie eine Funktion wie:

viewOrder :: PartialOrder -> ViewPartialOrder 
viewOrder (PartialOrder xs relation) = ... 

dann die ViewPatterns Erweiterung verwenden Code wie folgt zu schreiben:

f (viewOrder -> ViewPartialOrder xs le) = ... 

Natürlich sollten Sie kommen mit besseren Namen für diese Dinge: P!

Es gibt keine Möglichkeit, den gleichen Effekt implizit (dh ohne die viewOrder-Funktion), für besser oder schlechter. Ich denke, es ist normalerweise eine gute Sache, die deutlich macht, dass Sie nicht mit der tatsächlichen Implementierung des Typs übereinstimmen.

+0

Beat mich durch Sekunden! –

+0

@ChrisTaylor: Die gute altmodische "schnellste Waffe im West-Problem": P. –

+1

Die neue Erweiterung PatternSynonyms liefert, was Sie wollen, aber es ist noch nicht ganz verfügbar. – augustss

3

Der Vorschlag, ein Ansichtsmuster zu verwenden, ist ein guter Vorschlag, aber Sie können den gleichen Effekt ohne ein Ansichtsmuster erreichen, indem Sie die "Ansicht", die ja nur eine Funktion ist, vorkompoziieren.

So

gegeben
viewOfPartialOrder :: PartialOrder -> ViewPartialOrder 
viewOfPartialOrder (PartialOrder xs relation) = ... 

als Tichon Jelvis (unter einem etwas anderen Namen) vorgeschlagen, statt

doSomethingWithAPartialOrder :: PartialOrder a -> Whatever 
doSomethingWithAPartialOrder (viewOfPartialOrder -> ViewPartialOrder xs le) = ... 

Sie

doSomethingWithAView :: ViewPartialOrder a -> Whatever 
doSomethingWithAView (ViewPartialOrder xs le) = ... 

doSomethingWithAPartialOrder :: PartialOrder a -> Whatever 
doSomethingWithAPartialOrder = doSomethingWithAView . viewOfPartialOrder 

definieren Persönlich finde ich es leichter um Code in der letztgenannten Weise zu bearbeiten, aber Sie sollten wählen, was Sie persönlich bevorzugen.