5

想象这样一个函数:

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

该函数IO使用 aFoo和其他值执行一些操作。该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效果,因此每次都会生成它。是否有一种原生的、内置的 ghc方式来执行某种缓存,以便Foo生成一次值——用于生成的闭包?我想这一切都与拳击有关,但我从来没有想过如何在不使用脏的情况下做到这一点IORef,扩展 的参数bar,这很难看。

4

1 回答 1

12

您真正提出的要求会破坏引用透明度,这是 Haskell 中的一个很大的“不”。所以这给我留下了一个问题,我应该向您展示unsafeLaunchMissiles一种方法(有时,如果您很幸运并且优化不会破坏它)您真正提出的但非常不鼓励的方法,或者我应该展示一种干净的方式改变类型只是一点点?让我试试后者。

如果您bar改为使用以下类型:

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

然后你可以在一个do块中使用:

f <- bar myX

或者,如果您认为这错过了重新定义bar采取 an 的意义X,那么请保留您的第一个类型 forbar并执行

f <- bar =<< foo myX
于 2014-09-04T10:14:43.397 回答