Me gustaría ver si es factible tener una clase de tipo para convertir una cosa en otra y viceversa a partir de una asignación de [(a,b)]
.Tipo de conversión general clase
Este ejemplo debe ilustrar lo que me gustaría hacer:
data 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
Aquí es mi puñalada en hacer este trabajo:
{-# 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 fácil de hacer esto con la definición de dos casos para la la conversión va de cualquier manera pero me gustaría solo tener que declarar una como en el primer ejemplo. ¿Alguna idea de cómo podría hacer esto?
Editar: Por factible Es decir, se puede hacer esto sin superposición casos cualquier otra extensión desagradables?
Por simplicidad, podría doblar todos los pragmas de 'IDIOMA' en una lista separada por comas: '{- # LANGUAGE MultiParamTypeClasses, ... # -}'. –
@Antal S-Z: Sí, el asunto de las líneas separadas es solo un hábito mío. Utilizo un editor bastante simple para Haskell y agrego/quito pragmas mientras que refactorizar el código es más fácil si son autónomos. –
Eso es justo; Nunca he tenido más de uno o dos en un proyecto, por lo que refactorizarlos no ha sido un problema importante. Puedo ver la ventaja, sin embargo, ahora que lo pienso. –