2014-09-04 100 views
5

緩存內部想象這樣的功能:具有部分應用函數

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

即函數執行一些IO使用Foo和其他值的東西。該Foo值必須被傳遞到bar,並且可以從IO從這個被檢索:現在

foo :: X -> IO Foo 

ABCX都是純純值。使用X

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

而且Foo將在bar功能產生:我寧願喜歡這樣的bar功能。如果我這樣做:

let f = bar myX 

f :: A -> B -> C -> IO()。如果我多次調用該函數,X的值由於部分應用程序而保持不變,但由於它是IO效果,因此每次都會生成該值。是否有一個本地內置-GHC執行某種緩存方式,使生成Foo值一次 - 爲生成的封?我想這是所有拳擊相關的,但我從來沒有想出如何做到這一點,而不使用髒IORef,擴大bar,這是醜陋的參數。

回答

12

你真正要求的東西會打破參照透明度,這是Haskell中的一個很大的「否」。所以這給我留下了這個問題,我應該向你展示那種(有時候,如果你幸運的話,優化不會打破它)的方法,你真正問的但是非常灰心的,或者我應該展示乾淨的方式只是改變了一些類型?讓我試試後者。

如果你讓你bar有以下類型,而不是:

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

然後你可以使用,在do塊:

f <- bar myX 

或者,如果你認爲錯過重新定義的點bar採取X,然後改爲保留您的第一個類型爲bar並做

f <- bar =<< foo myX 
+1

是啊,我知道了'unsafeScheisse'功能,我不希望出現這種情況。你的解決方案讓我想到我經常使用的東西,比如傳遞給'control'的函數。我喜歡它,這聽起來很有希望。 – phaazon 2014-09-04 11:18:23