Haskell polymorphe Funktion zum Konvertieren zwischen algebraischen Datentypen

7

Ich habe zwei Haskell-Funktionen, die zwischen zwei algebraischen Datentypen konvertieren.

%Vor%

Aber ich möchte eine polymorphe Funktion machen, die sowohl algebraische Datentypen als auch Konvertierungen zwischen ihnen verwendet.

%Vor%

Aber Haskell leitet aus "foo A = C" ab, dass die Funktion

ist %Vor%

Ich habe versucht, die Datentypen Instanzen einer Klasse foo Polymorph zu machen, aber es hat nicht funktioniert.

%Vor%

Irgendwelche Ideen?

    
Paamayim Nekudotayim 07.08.2014, 21:09
quelle

3 Antworten

14

Dies ist sehr natürlich mit TypeFamilies . Sie definieren eine Typ-Level-Funktion

%Vor%

Dann wird Ihre Unterschrift

%Vor%

Wenn Sie nur mit Typen herumspielen würden, die Sie tun würden, aber da Sie auf der Werteebene ein anderes Verhalten haben wollen (ein A von einem C zurückgeben usw.), müssen wir unsere Fälle tatsächlich verteilen über Instanzen einer neuen Typklasse:

%Vor%

( Live-Demo )

Schließlich können Sie Converted zu einer Synonymfamilie vom geschlossenen Typ machen, wenn Sie den aktuellen GHC verwenden, oder sie durch Verschieben der Instanzen innerhalb der Convertable -Instanzdeklarationen "assoziieren".

    
jberryman 07.08.2014, 21:22
quelle
4

Nun, die Signatur in Ihrem letzten Codefragment ist immer noch falsch. Es wäre nicht foo :: Abcd a => a -> Ab , denn wenn a ~ Ab , dann sollte die Funktion ein Cd , nicht ein Ab zurückgeben.

Es gibt ein paar verschiedene Arten zu tun, was Sie wollen. Zuerst erkennen Sie, dass das, was Sie zu tun versuchen, ein gemeinsames Verhalten ist, das nicht auf einem Typ, sondern auf einer Beziehung zwischen zwei Typen basiert. Dies ist im Grunde der Zweck einer Multiparameter-Typklasse (was wahrscheinlich der einfachste Weg ist, dies zu erreichen).

%Vor%

BEARBEITEN: Beachten Sie, dass meine Antwort vollständig jberryman's entspricht, die Typenfamilien verwendet. Das ist, was ich mit "ein paar Arten zu tun, was du willst" meine.

    
Mark Whitfield 07.08.2014 21:23
quelle
1

Ein anderer Weg wäre die Verwendung der Erweiterungen MultiParamTypeClasses und FunctionalDependencies :

%Vor%

Demo:

%Vor%     
Sibi 07.08.2014 22:13
quelle

Tags und Links