Je ne pense pas qu'il existe un moyen de le faire directement, malheureusement. Avec une fonction, vous pouvez utiliser flip
pour appliquer partiellement le second argument, mais cela ne fonctionne pas avec les constructeurs de type Either
.
La chose la plus simple est l'enveloppant probablement dans un 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)
Emballage avec newtype
est également le moyen standard pour créer plusieurs instances pour un seul type, tels que Sum
et Product
cas étant de Monoid
pour numérique les types. Sinon, vous ne pouvez avoir qu'une seule instance par type.
De plus, en fonction de ce que vous voulez faire, une autre option est d'ignorer Functor
et définir votre propre classe de type comme celui-ci:
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)
De toute évidence, cette classe est deux fois plus de plaisir en tant que régulier Functor
. Bien sûr, vous ne pouvez pas créer une instance Monad
très facilement.
En relation: http://stackoverflow.com/questions/1827645 En bref, ce n'est pas possible dans Haskell tel qu'il est actuellement. – ephemient
En aparté, le titre de cette question n'est pas très clair, mais je ne suis pas sûr de ce qui serait mieux. –
J'ai proposé un titre plus précis. –