Wie man einen Operator erhält, der absolute und relative Werte in Haskell addiert / subtrahiert

8

(Entschuldigung für den seltsamen Titel, aber ich konnte mir keinen besseren vorstellen.)

Für ein persönliches Haskell-Projekt möchte ich die Begriffe "absolute Werte" (wie eine Frequenz) und relative Werte (wie das Verhältnis zwischen zwei Frequenzen) haben. In meinem Kontext macht es keinen Sinn, zwei absolute Werte hinzuzufügen: Man kann relative Werte hinzufügen, um neue relative Werte zu erzeugen, und einen relativen Wert zu einem absoluten Wert addieren, um einen neuen absoluten Wert zu erzeugen (und ebenfalls für die Subtraktion).

Ich habe Typklassen für diese definiert: siehe unten. Beachten Sie jedoch, dass die Operatoren ##+ und #+ eine ähnliche Struktur haben (und ebenso für ##- und #- ). Daher würde ich es vorziehen, diese Operatoren zusammenzuführen, so dass ich einen einzigen Additionsoperator habe, der einen relativen Wert hinzufügt (und ebenso einen einzelnen Subtraktionsoperator, der zu einem relativen Wert führt). UPDATE: Um das klarzustellen, ist es mein Ziel, meine ##+ und #+ zu einem einzigen Operator zusammenzufassen. Mein Ziel ist nicht , dies mit dem vorhandenen Operator ( Num ) + zu vereinheitlichen.

Ich sehe jedoch nicht, wie man das mit Typklassen macht.

Frage: Kann das gemacht werden, und wenn ja, wie? Oder sollte ich nicht versuchen?

Folgendes habe ich derzeit:

%Vor%     
Marnix Klooster 02.04.2013, 06:56
quelle

3 Antworten

9

Ich glaube, du suchst ein Konzept namens Torsor . Ein Torsor besteht aus einem Satz von Werten, einem Satz von Unterschieden und einem Operator, der einem Wert einen Unterschied hinzufügt. Außerdem muss die Menge der Unterschiede eine additive Gruppe bilden, so dass Unterschiede auch addiert werden können.

Interessanterweise sind Torsors überall. Gängige Beispiele sind

  • Punkte und Vektoren
  • Daten und Datumsunterschiede
  • Dateien und Diffs

usw.

Eine mögliche Haskell Definition ist:

%Vor%

Hier einige Beispiele:

%Vor%

Beachten Sie im letzten Fall, dass die beiden Sätze der Torsos keine andere Menge sein müssen, wodurch Sie Ihre relativen Werte einfach addieren können.

Weitere Informationen finden Sie unter eine viel schönere Beschreibung im Roman Cheplyakas Blog

    
aleator 02.04.2013, 08:36
quelle
8

Ich glaube nicht, dass Sie versuchen sollten, diese Operatoren zu vereinen. Das Subtrahieren von zwei Vektoren und das Subtrahieren von zwei Punkten sind grundsätzlich unterschiedliche Operationen. Die Tatsache, dass es schwierig ist, sie als das Gleiche im Typsystem darzustellen, ist nicht das Typsystem, das peinlich ist - weil diese beiden Konzepte wirklich unterschiedliche Dinge sind!

Der mathematische Rahmen hinter dem, mit dem Sie arbeiten, ist der affine Raum .

Diese sind bereits in Haskell im Vektorraum-Paket verfügbar (do cabal install vector-space an der Eingabeaufforderung). Anstatt Klassen mit mehreren Parametertypen zu verwenden, verwenden sie Typenfamilien, um jedem Punkttyp (absoluten Typ) einen (relativen) Vektortyp zuzuordnen.

Hier ist ein minimales Beispiel, das zeigt, wie Sie Ihre eigenen absoluten und relativen Datentypen und deren Interaktion definieren:

%Vor%     
Chris Taylor 02.04.2013 08:13
quelle
8

Sie haben zwei Antworten, die Ihnen sagen, was Sie tun sollten, hier ist eine andere Antwort, die Ihnen sagt, wie Sie tun können, wonach Sie gefragt haben (was vielleicht keine gute Idee ist). :)

%Vor%

Das Überladen für (#+) macht es sehr flexibel. Zu flexibel, IMO. Die einzige Einschränkung ist, dass der Ergebnistyp durch die Argumenttypen bestimmt wird (ohne diesen FD wird der Operator fast unbrauchbar, weil er nichts einschränkt).

    
augustss 02.04.2013 09:46
quelle

Tags und Links