想象一个这样的函数:
bar :: Foo -> A -> B -> C -> IO ()
该函数执行一些
IO
使用 Foo
的东西和其他值。 Foo
值必须传递给 bar
, 并且可以从 IO
检索通过这个:foo :: X -> IO Foo
现在,
A
, B
, C
和 X
都是普通的纯值。我更喜欢这样的 bar
功能:bar :: X -> A -> B -> C -> IO ()
和
Foo
将在 bar
中生成函数使用 X
值(value)。如果我这样做:let f = bar myX
f :: A -> B -> C -> IO ()
.如果我多次调用该函数,X
由于部分应用,值保持不变,但因为它是 IO
效果,每次都会生成。是否有一种本地的、内置的 ghc 方式来执行某种缓存,以便 Foo
值生成一次——对于生成的闭包?我想这都是与拳击有关的,但我从来没有想过如何在不使用脏的情况下做到这一点 IORef
,扩展bar
的参数,这是丑陋的。
最佳答案
您实际上要问的是会破坏引用透明度,这是 Haskell 中的一个大“不”。所以这给我留下了一个问题,我应该给你看 unsafeLaunchMissiles
一种方法(有时,如果你很幸运并且优化不会破坏它)你真正问但非常不鼓励的方法,或者我应该展示稍微改变类型的干净方式?让我试试后者。
如果你让你的 bar
改为使用以下类型:
bar :: X -> IO (A -> B -> C -> IO ())
然后你可以在
do
中使用堵塞:f <- bar myX
或者,如果您认为这忽略了重新定义
bar
的要点。拿个 X
,然后保留您的第一个类型 bar
并做f <- bar =<< foo myX
关于haskell - 使用部分应用的函数缓存内部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25661781/