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?
Dies ist sehr natürlich mit TypeFamilies
. Sie definieren eine Typ-Level-Funktion
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:
( 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".
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.