所以,我是一位经验丰富的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
答案 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
查看您提供的此功能,其执行不会产生任何副作用。对于给定的输入a
和b
,我们将始终获得相同的输出值,因此这已经是一个纯函数。
要明确的是,在函数式编程中包含条件的函数绝对没有问题。但是,我们经常使用模式匹配而不是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