Ich würde gerne sehen, ob es möglich ist, eine Klasse für die Umwandlung einer Sache in eine andere und wieder zurück von einer Zuordnung von [(a,b)]
haben.Allgemeine Umwandlung Typ Klasse
sollte diesem Beispiel veranschaulichen, was ich tun möchte:
zu machen, diese Arbeitdata XX = One | Two | Three deriving (Show, Eq)
data YY = Eno | Owt | Eerht deriving (Show, Eq)
instance Convert XX YY where
mapping = [(One, Eno), (Two, Owt), (Three, Eerht)]
-- // How can I make this work?:
main = do print $ (convert One :: YY) -- Want to output: Eno
print $ (convert Owt :: XX) -- Want to output: Two
Hier ist mein Stich:
{-# LANGUAGE MultiParamTypeClasses #-}
import Data.Maybe(fromJust)
lk = flip lookup
flipPair = uncurry $ flip (,)
class (Eq a, Eq b) => Convert a b where
mapping :: [(a, b)]
mapping = error "No mapping defined"
convert :: a -> b
convert = fromJust . lk mapping
-- // This won't work:
instance (Convert a b) => Convert b a where
convert = fromJust . lk (map flipPair mapping)
Es ist leicht, das für die mit der Definition zwei Instanzen zu tun Konvertierung in beide Richtungen, aber ich möchte nur eine wie im ersten Beispiel zu deklarieren. Irgendeine Idee, wie ich das machen könnte?
Edit: Durchführbar meine ich, kann dies ohne überlappende Instanzen irgendwelche andere böse Erweiterungen erfolgen?
Der Einfachheit halber könnten Sie alle "LANGUAGE" Pragmas in eine durch Kommas getrennte Liste falten: '{- # LANGUAGE MultiParamTypeClasses, ... # -}'. –
@Antal S-Z: Yeah, die separaten Zeilen Sache ist nur eine Angewohnheit von mir. Ich verwende einen ziemlich einfachen Editor für Haskell und das Hinzufügen/Entfernen von Pragmas, während das Refactoring von Code einfacher ist, wenn sie in sich abgeschlossen sind. –
Das ist fair; Ich hatte nie wirklich mehr als ein oder zwei in einem Projekt, also war das Refactoring kein großes Problem. Ich kann den Vorteil sehen, jetzt, wo ich darüber nachdenke. –