No creo que haya una manera de hacerlo directamente, desafortunadamente. Con una función puede usar flip
para aplicar parcialmente el segundo argumento, pero eso no funciona con constructores de tipo como Either
.
Lo más sencillo es, probablemente, envolviéndolo en una newtype
:
newtype Mirror b a = Mirrored (Either a b)
instance Functor (Mirror e) where
fmap _ (Mirrored (Right a)) = Mirrored $ Right a
fmap f (Mirrored (Left b)) = Mirrored $ Left (f b)
de envolver con newtype
es también la forma estándar para crear varias instancias de un solo tipo, tales como Sum
y Product
siendo ejemplos de Monoid
para numérico tipos. De lo contrario, solo puede tener una instancia por tipo.
Además, dependiendo de qué es lo que quiere hacer, otra opción es hacer caso omiso de Functor
y definir su propio tipo de clase de esta manera:
class Bifunctor f where
bimap :: (a -> c) -> (b -> d) -> f a b -> f c d
instance Bifunctor Either where
bimap f _ (Left a) = Left $ f a
bimap _ g (Right b) = Right $ g b
instance Bifunctor (,) where
bimap f g (a, b) = (f a, g b)
Obviamente, esa clase es dos veces tan divertido como un habitual Functor
. Por supuesto, no puede hacer una instancia Monad
de eso muy fácilmente.
Relacionado: http://stackoverflow.com/questions/1827645 En resumen, no es posible en Haskell tal como está ahora. – ephemient
Como un aparte, el título de esta pregunta es poco claro, pero no estoy seguro de qué sería mejor. –
Propuse un título más preciso. –