【问题标题】:F# - keeping track of stateF# - 跟踪状态
【发布时间】:2016-02-01 19:36:44
【问题描述】:

我正在用 F# 构建一个缓存系统。我想做的一件事是跟踪程序运行期间的总缓存命中和缓存未命中。所以,例如我可能有这样的功能:

member this.Exists key =
            match HttpRuntime.Cache.Get(key) with
            | null -> false
            | result -> true

在真正的空情况下,我还想增加一个未命中计数器,在错误的情况下,我还想增加一个命中计数器。现在我可以使用可变变量并且没有问题,但是我想知道如何使用纯函数方法或更惯用的 F# 方法来解决这个问题,最终目标是能够显示当前的缓存计数程序运行时对用户的命中和未命中。

【问题讨论】:

  • 缓存本身是高度非纯的,所以我不会为任何纯粹的状态单子而烦恼......只需使用可变变量 - 像这样的情况正是你应该使用这些 IMO 的地方(它是反正是无害的副作用)
  • 顺便说一句:如您所见,您不会在任何地方使用this 或result - 这就是为什么您通常写member __.Exists key = ... 和| _ -> true 来代替
  • 无 - 确实 __ 是一个有效的 name - 之所以使用它是因为它与 I don't care 包罗万象的模式非常相似_
  • 是的 - 任何你喜欢的名字 - 常见的选择是 this、x 和 __ ;) - 如果你使用 VisualStudio,你可以自己选择 PowerTools,他们会推荐一些那些(有点像 Resharper 做的)给你的
  • 请记住,如果您只使用可变变量,则此类计数器将不是线程安全的。这可以通过执行@GuyCoder 建议的IObservable 方法或简单地使用Interlocked.Increment / Decrement 来解决。

标签: f#


【解决方案1】:

我也不会太担心纯粹的性能计数。根据定义,它是一种副作用,因此为它保留一些可变状态是有意义的。

例如,您可以将static(或不static)成员添加到您的班级并对其进行变异:

type Cache() = 
  static let mutable missCounter = 0
  static let mutable hitCounter = 0
  member this.Exists key =
    match HttpRuntime.Cache.Get(key) with
    | null -> missCounter <- missCounter + 1; false
    | result -> hitCounter <- hitCounter + 1; true

【讨论】:

  • 我认为关键字 HttpRuntime.Cache 应该敲响一些警钟。这本质上是并发的,而且我一般有点担心这样的代码,特别是在 HttpRuntime 上下文中。 Fyodor Soikin 在上面也提到了这一点。
猜你喜欢
  • 1970-01-01
  • 2012-11-16
  • 2011-11-14
  • 1970-01-01
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多