使用部分应用的函数缓存内部



想象这样一个函数:

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

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

foo :: X -> IO Foo

现在,ABCX都是纯值。我更喜欢这样一个bar函数:

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

并且Foo将使用X值在bar函数中生成。如果我这样做:

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

最新更新