想象一下这样的功能:

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

该函数使用IO和其他值执行一些Foo内容。 Foo值必须传递给bar,并且可以通过以下方式从IO检索:
foo :: X -> IO Foo

现在,ABCX都是纯净值。我想要这样的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/

10-12 01:29
查看更多