F#中的递归lambda

thr*_*thr 7 recursion lambda f# functional-programming fixpoint-combinators

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

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 ""
Run Code Online (Sandbox Code Playgroud)

这是我在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 "" 
Run Code Online (Sandbox Code Playgroud)

但正如您可能预期的那样,无法在其自身内部引用匿名函数,这在我放置## RECURSE ##时需要

Dar*_*rio 17

是的,可以使用所谓的y组合器(或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" *)
Run Code Online (Sandbox Code Playgroud)

我不知道F#的文章,但这个haskell条目也可能有用.

但是:如果有任何替代方案,我不会使用它们 - 它们很难理解.

您的代码(省略此处的类型注释)是一种标准结构,更具表现力.

let listToString lst =

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

    loop "" lst
Run Code Online (Sandbox Code Playgroud)