【问题标题】:Memoizing tail call optimized recursive functions in F# [duplicate]在 F# 中记忆尾调用优化的递归函数 [重复]
【发布时间】:2011-04-13 22:54:21
【问题描述】:

可能重复:
Combine memoization and tail-recursion

所以下面是我写的代码,尾调用使用累加变量优化

let rec counter init count = 
    if init = 1 then count + 1 else
    match init with
    | Even value -> (counter (value/2)  (1 + count))
    | Odd value -> (counter ((3 * value) + 1) (count+1))

let SeqBuilder (initval:int) : int =
    counter initval 0

我如何记住这个?我在尝试记忆时遇到的问题是递归调用必须转到记忆对象,所以你必须有一个......递归对象?

还是简单很多,我只是缺乏经验?

【问题讨论】:

    标签: f# memoization


    【解决方案1】:

    F# 允许你定义一个 递归值(就像你提到的递归对象),所以如果你有 memoize2 函数来做记忆(采用两个参数的函数 - 让它兼容你的counter),那么你可以写:

    let rec counter = memoize2 (fun init count ->
      if init = 1 then count + 1 else 
      match init with 
      | Even value -> (counter (value/2) (1 + count)) 
      | Odd value -> (counter ((3 * value) + 1) (count+1)) )
    

    像这样的递归引用可能很危险,因此 F# 插入了一些运行时检查。它还会发出警告FS0040 来通知您,但在这种情况下,递归是正确的(如果在初始化期间访问递归引用,则可能会出现问题 - 这里我们只在稍后使用它,当函数已经声明时,所以一切都很好)。您可以通过添加 #nowarn "40" 来禁用警告。

    【讨论】:

    • 现在你的计数器不是尾递归的
    猜你喜欢
    • 2018-03-08
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 2010-10-20
    • 2012-11-26
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    相关资源
    最近更新 更多