Ich bin ziemlich sicher, dass dies eine einfache Lösung hat, aber es entzieht sich mir und ich kann nicht scheinen, eine klare Antwort zu finden.Inverse Aufhebung auf anwendungsspezifischen Funktoren
Normalerweise, wenn liftA2
unter der Annahme der binären Funktion Anwendung bereits einmal angehoben worden ist, sieht die Signatur wie folgt aus:
liftA2' :: (Applicative f1, Applicative f)
=> (f a -> f b -> f c) -> f1 (f a) -> f1 (f b) -> f1 (f c)
Ist es möglich, die „inverse“ von zum Beispiel liftA2
wie anzuwenden:
inverseA2 :: (Applicative f, Applicative f1)
=> (f a -> f b -> f c) -> f (f1 a) -> f (f1 b) -> f (f1 c)
Als ein konkretes Beispiel, würde Ich mag die Funktion erhalten:
f :: ([a] -> [b] -> [c]) -> [Maybe a] -> [Maybe b] -> [Maybe c]
Ein Weg, um „Pack“ jedes Argument [Maybe a] -> Maybe [a]
und „auspacken“ Maybe [a] -> [Maybe a]
das Ergebnis der Anwendung eines normalen liftA2
zu greifen wäre. Ich möchte das vermeiden, da, wie Sie sich vorstellen können, die Verpackung destruktiv ist (z. B. pack [Just 1, Nothing, Just 2] == Nothing
).
Update: wie @ user2407038 wies darauf hin, für f
, um die gegebene Funktion, die Sie unbedingt benötigen eine Funktion entlang der Linien von [Maybe a] -> [a]
anzuwenden, die tut Informationen zu verlieren. Für diese beiden speziellen Funktoren gibt es keine offensichtliche Möglichkeit, die zusätzliche Anforderung zu erfüllen. Aber für alle anderen zwei Funktoren f
, f1
, die eine invertierbare Funktion haben forall a . f a -> f1 a
die Antwort akzeptiert passt perfekt als eine Lösung für diese Frage.
Nehmen Sie 'f :: [Int] -> [Char] -> [Int]; f x y = [Länge x + Länge y] '. Was würdest du von 'inverseA2 f :: [Maybe Int] -> [Vielleicht Char] -> [Maybe Int] 'erwarten? Was ist mit 'f x y = [Länge x + Länge y, Kopf x]'? Ich bin nicht sicher, was die allgemeine Definition wäre ... – chi
Damit 'f' die gegebene Funktion anwenden kann, muss es ein' [a] 'aus einem' [Maybe a] 'erzeugen (natürlich gibt es keinen Weg um '[a]' von '[Maybe b]' zu bekommen, da es keine Möglichkeit gibt, 'a' von' b' zu bekommen und somit * unbedingt * eine Funktion '[Maybe a] -> [a]' - und wie Sie bemerkt haben, verliert diese Funktion notwendigerweise Informationen. Dasselbe gilt für den allgemeinen Fall - es gibt wenige Funktoren 'f1, f2', die eine invertierbare Funktion' forall a 'haben. f1 a -> f2 a'. – user2407038
@ user2407038 also gab es einen Grund, warum ich keine einfache Antwort gefunden hatte, da ich das falsche Problem betrachtete. Danke, dass du auf die invertierbaren Funktionen hingewiesen hast! Ich werde mehr darüber nachdenken. –