纯功能编程

时间:2016-11-28 18:46:52

标签: f# functional-programming

所以,我是一位经验丰富的OOP程序员(主要是C ++),刚刚开始使用函数式编程。根据我的理解,在一个纯粹的功能范例中,函数不应该有条件,应该使用currying尽可能地分解。有人可以为我提供以下示例的“纯”功能版本吗?最好使用将成为功能范例一部分的每一种严格技术:

let rec greatestCommonFactor a b =
    if a = 0 then b
    elif a < b then greatestCommonFactor a (b - a)
    else greatestCommonFactor (a - b) b

1 个答案:

答案 0 :(得分:16)

您提供的示例函数已经完全正常运行。当我们谈论函数纯度时,我们实际谈论的是函数referentially transparent的属性。

如果表达式可以替换为其值而不改变程序的效果,则表达式是引用透明的。举一个简单的例子,想象一下函数:

let add2 x = x + 2

现在,在我们的程序中出现值add2 2的任何地方,我们可以替换值4而不改变程序的行为。

现在想象一下,我们在打印到控制台的函数中添加了一些额外的行为:

let add2Print x =
    printfn "%d" x
    x + 2

虽然函数的结果与以前相同,但我们不能再使用值4执行值替换而不更改程序的行为,因为我们的函数具有打印到附加的附加副作用控制台。

此功能不再是引用透明的,因此不是纯函数。

let rec greatestCommonFactor a b =
    if a = 0 then b
    elif a < b then greatestCommonFactor a (b - a)
    else greatestCommonFactor (a - b) b

查看您提供的此功能,其执行不会产生任何副作用。对于给定的输入ab,我们将始终获得相同的输出值,因此这已经是一个纯函数。

要明确的是,在函数式编程中包含条件的函数绝对没有问题。但是,我们经常使用模式匹配而不是if/elif/else表达式,但在您所描述的示例中,这纯粹是风格。使用模式匹配的函数的替代表达式是:

let rec greatestCommonFactor a b =
    match a with
    |0 -> b
    |a' when a' < b -> greatestCommonFactor a' (b - a')
    |a' -> greatestCommonFactor (a' - b) b