2014-09-04 4 views
5

Stellen Sie sich vor, eine solche Funktion:Caching Einbauten mit einer teilweise angewandte Funktion

bar :: Foo -> A -> B -> C -> IO() 

Diese Funktion führt einige IO Sachen ein Foo und anderen Werten. Der Foo Wert muss auf bar weitergegeben werden, und kann von IO über diese abgerufen werden:

foo :: X -> IO Foo 

Nun A, B, C und X sind alle plain pure Werte. Ich möchte lieber eine solche bar Funktion:

bar :: X -> A -> B -> C -> IO() 

Und Foo würde in der bar Funktion erzeugt werden, um den X-Wert. Wenn ich das tue:

let f = bar myX 

f :: A -> B -> C -> IO(). Wenn ich diese Funktion mehrmals anrufe, bleibt der Wert X wegen der teilweisen Anwendung gleich, aber da es sich um einen IO Effekt handelt, wird er jedes Mal generiert. Gibt es eine native, eingebaute-ghc Möglichkeit, eine Art Caching durchzuführen, so dass der Foo Wert einmal generiert wird - für die generierte Schließung? Ich schätze, es ist alles im Zusammenhang mit dem Boxen, aber ich habe nie herausgefunden, wie man das macht, ohne schmutzig zu verwenden IORef, die Parameter von bar erweiternd, das hässlich ist.

Antwort

12

Was Sie wirklich fragen, würde referentielle Transparenz brechen, ein großes "Nein" in Haskell. Also, das lässt mich mit der Frage, sollte ich Ihnen die Art von Methode zeigen, die (manchmal, wenn Sie Glück haben und Optimierungen nicht brechen), was Sie buchstäblich fragen, aber wird stark davon abgeraten, oder sollte ich den sauberen Weg zeigen das ändert die Typen nur ein wenig? Lass mich das letztere versuchen.

Wenn Sie machen Ihre bar haben die folgende Art statt:

bar :: X -> IO (A -> B -> C -> IO()) 

Dann können Sie verwenden, in einem do Block:

f <- bar myX 

Alternativ, wenn Sie denken, dass der Punkt der Neudefinition vermißt bar nehmen Sie eine X, dann halten Sie stattdessen Ihre erste Typ für bar und tun

f <- bar =<< foo myX 
+1

Ja, ich kenne die 'unsafeScheiße' Funktionen, das will ich nicht. Deine Lösung lässt mich an etwas denken, das ich oft verwende, wie die Funktion, die an 'control' übergeben wurde. Ich mag es, es klingt vielversprechend. – phaazon

Verwandte Themen