【问题标题】:Recursive lambdas in F#F# 中的递归 lambda
【发布时间】:2010-10-28 11:37:27
【问题描述】:

以这个示例代码为例(暂时忽略它非常低效)

let listToString (lst:list<'a>) = ;;' prettify fix

    let rec inner (lst:list<'a>) buffer = ;;' prettify fix
        match List.length lst with 
        | 0 -> buffer
        | _ -> inner (List.tl  lst) (buffer + ((List.hd lst).ToString()))

    inner lst ""

这是我在 F# 中经常遇到的一种常见模式,我需要一个内部函数,它在某个值上递归自身 - 我只需要这个函数一次,有没有可能从其中调用 lambda自我(一些神奇的关键字或什么)?我希望代码看起来像这样:

let listToString2 (lst:list<'a>) = ;;' prettify fix

    ( fun 
        (lst:list<'a>) buffer -> match List.length lst with ;;' prettify fix
                                 | 0 -> buffer
                                 | _ -> ##RECURSE## (List.tl lst) (buffer + ((List.hd lst).ToString())) 
    ) lst "" 

但正如您可能期望的那样,无法在其内部引用匿名函数,这是我放置##RECURSE##的地方所需要的

【问题讨论】:

    标签: recursion lambda functional-programming f# fixpoint-combinators


    【解决方案1】:

    是的,可以使用所谓的y-combinators(或fixed-point combinators)。例如:

    let rec fix f x = f (fix f) x
    
    let fact f = function
     | 0 -> 1
     | x -> x * f (x-1)
    
    
    let _ = (fix fact) 5 (* evaluates to "120" *)
    

    我不知道有关 F# 的文章,但这个 haskell entry 也可能会有所帮助。

    但是:如果有其他选择,我不会使用它们 - 它们很难理解。

    您的代码(此处省略类型注释)是标准构造,并且更具表现力。

    let listToString lst =
    
        let rec loop acc = function
            | []    -> acc
            | x::xs -> loop (acc ^ (string x)) xs
    
        loop "" lst
    

    【讨论】:

      【解决方案2】:

      请注意,虽然您说您只使用该函数一次,但从技术上讲,您两次通过名称引用它,这就是给它一个名称的原因。

      【讨论】:

        猜你喜欢
        • 2016-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-26
        相关资源
        最近更新 更多