想象一下这样的功能:
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
。如果我这样做:let f = bar myX
f :: A -> B -> C -> IO ()
。如果我多次调用该函数,由于部分应用,X
值保持不变,但是由于它是IO
效果,因此每次都会生成。是否存在 native 的内置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/