【问题标题】:FSharp Parameterless Function Caching, does it always cache?FSharp 无参数函数缓存,它总是缓存吗?
【发布时间】:2015-09-01 13:50:06
【问题描述】:

根据http://en.wikibooks.org/wiki/F_Sharp_Programming/Caching

F# 自动缓存任何不接受的函数的值 参数

那么为什么会这样呢?

let random() = System.Random().Next()

随机是单位 -> int 我希望每次调用 random() 时都会缓存输出值并返回相同的 int。

【问题讨论】:

  • random() 采用参数(),即unit。你混淆了一个函数和一个变量。 let random = System.Random().Next() 初始化一个变量 random,它将在多次调用时返回相同的值。
  • FSharp is supposed to automatically cache the value of any function which takes no parameters. [需要引用](不,en.wikibooks.org/wiki/F_Sharp_Programming/Caching 不是 F# 的权威来源)
  • 为什么你认为F#应该自动缓存函数结果? (我不想嘲笑你 - 老实说,我想知道你从哪里得到的,以便尝试摆脱那里的错误信息)
  • @Luaan 我已经添加了引用,所以你可以看到我在哪里感到困惑。

标签: caching f#


【解决方案1】:

F# 3.0 规范没有这样说。

允许纯函数式语言执行这种“替换”(通常称为“引用透明性”),因为在纯函数式语言中,函数只不过是它的单个参数和它的单个返回值。不用说,F# 不是纯粹的函数式语言。

然而,这不是这里的问题。 random 不是一个没有参数的函数。它接受一个参数(unit 类型),并返回一个整数。正如您所指出的,random 的签名是 unit -> int - 这与没有参数的函数完全不同,后者的签名是 int;换句话说,一个本地人。

当一个函数接受或返回unit(或void)时,它不应该被记忆——这是一个明显的迹象,表明该方法有副作用。这不是一个固定的规则,但是...

【讨论】:

  • 我承认自己是 V.B.你已经注意到这是一个带单位的函数,所以它不是无参数的,但我现在很困惑,F# 是否缓存无参数函数?
  • 如果使用 无参数函数,你的意思是值,那么是的......如果你的意思是从 () 到没有的函数
  • @Luaan ...我认为我们不应该称之为 memoization - 我认为您在这里谈论的是referential transparency
  • @Carsten 嗯,这有点严格,但我想它更合适。
  • @HedgeHogFace 你仍然和刚开始时一样的困惑——无参数函数是一个值。每次执行 let i = 3 时,您都在创建一个新的无参数函数,该函数返回 3。如果您不研究这背后的代数,我可以看出这会造成多大的混乱 - 如果您不想深入研究数学,将无参数函数等同于简单值是一种合理的简化。
【解决方案2】:

看起来在问题中编码我的一个班轮的正确方法是

let good = 
    let r = System.Random()
    fun () -> r.Next()

这具有签名 (unit -> int)let r = System.Random() 行只会执行一次,即使 good() 可能会被多次调用。

下面这个不好。

let bad() =       
    let r = System.Random()   
    r.Next()

这具有签名 unit -> int。类似于问题中的一个班轮。这里 let r = System.Random() 行将在每次调用 bad() 时执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 2020-09-17
    相关资源
    最近更新 更多