Sie können die gesuchte Instanz nicht direkt erstellen.
Damit Typinferenz- und Typklassen funktionieren, gibt es eine gewisse Positionsabweichung bei der Sortierung von Argumenten in den Typen. Es wurde gezeigt, dass, wenn wir willkürliche Neuordnung der Argumente bei der Instanziierung von Typklassen zulassen, diese Art von Inferenz unhandlich wird.
Sie könnten eine Bifunctor
Klasse verwenden, die beide Argumente separat abbilden kann.
class Bifunctor f where
bimap :: (a -> b) -> (c -> d) -> f a c -> f b d
first :: (a -> b) -> f a c -> f b c
second :: (c -> d) -> f a c -> f a d
first f = bimap f id
second = bimap id
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)
Oder Sie könnten eine Flip
combinator wie verwenden:
newtype Flip f a b = Flip { unFlip :: f b a }
Generalized Versionen der beiden von ihnen sind in der Kategorie-Extras auf Hackage zur Verfügung. Letzteres enthält sogar eine Instanz für Functor (Flip Either a)
, weil Either
eine Bifunctor
ist. (Ich sollte wahrscheinlich beheben, dass nur eine PFunctor
erforderlich)
Schließlich ist die Reihenfolge der Argumente in einem Typkonstruktor wichtig bei der Bestimmung, welche Klassen Sie instanziieren können. Möglicherweise müssen Sie newtype wrappers (wie Flip
oben) verwenden, um die Argumente zu platzieren, wo sie sein müssen, um eine Instanz einer anderen Typklasse zu erstellen. Dies ist der Preis, den wir für die Ableitung von Typklassenbeschränkungen zahlen.
Related: http://stackoverflow.com/questions/1827645 Kurz gesagt, es ist nicht möglich in Haskell, wie es jetzt steht. – ephemient
Nebenbei ist der Titel dieser Frage etwas unklar, aber ich bin mir nicht sicher, was besser wäre. –
Ich schlug einen präziseren Titel vor. –