2016-04-05 27 views
8

Ich habe in den letzten Monaten in Haskell gegraben, ich bin in eine Situation mit Monaden geraten Ich bin mir nicht ganz sicher, wie ich damit umgehen soll.Haskell (a -> ma) -> m (a -> a) -> m (a -> a)

Ich habe einen Wert vom Typ a -> m a und einen zweiten Typ von m (a -> a) und ich brauche eine ihnen, so dass das Ergebnis der ersten endet als die Eingabe in die des zweiten und erzeugt m (a -> a) wenn möglich zu komponieren. Ich bin jetzt für den letzten Tag drangeblieben, und ich drehe meinen Kopf nicht darum herum. Ich nehme an, dass ich nach einer Funktion wie (a -> m a) -> m (a -> a) -> m (a -> a) suche. Ich kann ein konkreteres Beispiel geben, wenn es sinnvoller ist.

+2

Sie können * sort * tun, was Sie fragen, wenn Sie bereit sind, die monadischen Aktionen mit allen möglichen Eingabe 'a' Werte auf einmal im Voraus durchzuführen. Manchmal ist das was du willst - aber normalerweise nicht. –

Antwort

13

Sie können dies im Allgemeinen nicht tun. Das Problem ist Ihr Ergebnistyp: m (a -> a). Dies ist eine einzelne monadische Aktion, die eine Funktion erzeugt; aber Ihre erste Eingabe hat die Form a -> m a, die (potenziell) eine unterschiedliche monadische Aktion für jedes Argument erzeugt. So ist zum Beispiel für die [] monad [a -> a] Liste von Funktionen mit einer festen Länge, während a -> [a] eine unterschiedliche Länge für jedes Argument haben kann. Es gibt also keine Möglichkeit, den Funktionstyp im allgemeinen in den m zurückzuschieben; Eine ähnliche Frage finden Sie unter What is the general case of QuickCheck's promote function?.

Wenn a -> m a würde arbeiten, was Sie brauchen, dann können Sie Ihr m (a -> a) Argument in a -> m a drehen

\ x -> fmap ($ x) af 

und verwenden >=> (oder <=<, es ist nicht klar von Ihren Typen) zusammen, um die Funktionen zu komponieren.

+0

Ja! Die angeforderte Funktion würde eine Monad-Aktion auf eine anwendbare Aktion zurückstufen, was unmöglich ist. Was sie stattdessen tun sollten, ist das Upgrade der Applicative-Aktion auf eine Monad-Aktion. –

+0

Das ist im Allgemeinen, was ich dachte, ich würde tun müssen. Ich hatte einfach noch nicht die richtigen Worte dazu. –

Verwandte Themen