如果不是递归,该示例是什么?

时间:2019-07-02 16:45:43

标签: recursion functional-programming f#

以下是用F#(类似于OCaml的功能语言)编写的程序

let bind f opt =  
    match opt with 
    | Some v -> f v 
    | None -> None 

这是递归。

let example input =  
    let x = doSomething input 
    if x.IsSome then 
        let y = doSomethingElse (x.Value)  
        if y.IsSome then 
            let z = doAThirdThing (y.Value)  
            if z.IsSome then 
                let result = z.Value 
                Some result  
            else 
                None 
        else 
            None 
    else 
        None 

这不是递归。是什么呢?

2 个答案:

答案 0 :(得分:5)

这些都不是递归的。 F#中的递归函数使用rec关键字。更重要的是,递归函数会自行调用。我没有看到example中的任何地方使用了example。我没有看到bind中的任何地方使用了bind。这些只是功能。绑定之所以特别,是因为它被用于影响控制流的许多模式和技术中。您的示例函数也是如此,输入确实决定了控制流程。有时将这种技术称为“面向铁路的编程”或ROP,其中您拥有满意或“正确”或“某些”路径以及“失败”或“左侧”或“无”路径。有时人们使用Result类型来捕获有关左路径的其他详细信息。

作为有趣的历史轶事,长期留在西方文化中意味着邪恶或堕落,因为左手用于个人卫生。

https://fsharpforfunandprofit.com/rop/

https://en.wikipedia.org/wiki/Bias_against_left-handed_people

答案 1 :(得分:2)

该示例与递归无关。

第一段代码是“绑定”的实现-函数编程中常见模式的一部分。

它接受带有签名f和类型(a->Option<'b>)的值opt的函数Option<'a>。如果opt的值(opt等于Some v),则将函数f应用于opt的值。 (因此返回NoneSome b)。如果opt没有值(等于None),则返回None

第二个示例看起来像一个示例,该示例说明了如何在不使用“绑定”的情况下编写代码。

使用第一个示例中的bind函数,第二个示例可以写得更清楚:

let example input =  
    input
    |> doSomething
    |> bind doSomethingElse
    |> bind doAThirdThing