【问题标题】:Caching internals with a partially applied function使用部分应用函数缓存内部结构
【发布时间】:2014-09-04 09:24:36
【问题描述】:

想象一下这样的功能:

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 效果,因此每次都会生成它。是否有一种 nativebuilt-in-ghc 方式来执行某种缓存,以便为生成的闭包生成一次 Foo 值?我想这都是与拳击有关的,但我一直不知道如何在不使用脏 IORef 的情况下做到这一点,扩展 bar 的参数,这很难看。

【问题讨论】:

    标签: haskell caching closures partial-application


    【解决方案1】:

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

    如果您将 bar 改为以下类型:

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

    然后您可以在 do 块中使用:

    f <- bar myX
    

    或者,如果您认为将bar 重新定义为X 没有意义,那么请保留您的first 类型为bar 并执行

    f <- bar =<< foo myX
    

    【讨论】:

    • 是的,我知道 unsafeScheisse 函数,我不想要那个。你的解决方案让我想起了我经常使用的东西,比如传递给control的函数。我喜欢它,听起来很有希望。
    猜你喜欢
    • 1970-01-01
    • 2015-08-22
    • 2015-01-02
    • 1970-01-01
    • 2016-07-29
    • 2015-11-03
    • 1970-01-01
    • 2021-12-09
    • 2015-08-10
    相关资源
    最近更新 更多