函数式编程背后的动力
函数式编程背后的动力来源自数学,数学函数拥有很多不错的特色,函数化语言试图现实世界中模拟。
首先,我们以为一个数添加1的函数开始。
Add1(x) = x+1
它是什么意思呢?它似乎很简单,这意味着有一个操作,为一个数字加1。
我们先解释一些术语
在F#中定义是这样的:
let add1 x = x + 1
如果你在F#中的即使窗口输入(不要忘记双分号) ,就会看到结果(函数的签名):
val add1 : int -> int
我们仔细看一下输出:
注意类型没有被指定,但F #编译器猜测函数正在为整数服务。(这能改变吗?是的,因为我们会看到不久的)
数学函数中的一些特性与你之前在编程中的特性不一样。
这些属性提供了一些非常强大的好处,因此函数式编程语言试图在他们的设计中执行这些属性。让我们轮流看他们的每一个。
在命令式编程中,我们认为函数是在“do 做”或者“calculate 计算”。数学函数不做任何的计算,只是单纯的从输入映射到输出。事实上,另一种简单的定义函数是所有映射的集合。例如,我们可以在C#中简陋的定义这个“add1”函数:
int add1(int input)
{
switch (input)
{
case 0: return 1;
case 1: return 2;
case 2: return 3;
case 3: return 4;
etc ad infinitum
}
}
很显然,我们不能为每个可能值都添加一个分支,但是原则上是一样的。你可以看过绝对没有任何的计算,只是查找。
在数学函数中,输入和输入在逻辑上是两个不同的东西,它们都是预定义的。函数不能改变输入和输出-它只是从域中预存在的值映射到范围中一个预存在的值。
换句话说,计算这个函数不能对输入有任何的影响或者任何其他事情。记住,计算这个函数不是实际的计算或者操纵任何事,只是查找。
值的“不变性”很微妙但是很重要。如果我在做数学,我不希望在我加的时候改变我的数字,例如,如果我这样:
x = 5 y = x+1
我不希望当我给x加什么数的时候x改变。我希望返回一个y,x原封不动。在数学的世界中,整数作为一个不可改变的集合已经存在,“add1”函数简单的定义他们之间的关系。
重复结果而且无副作用的函数称为“纯函数”,我们可以用它们做一些有意思的事
所以你可以看到如果我们用编程语言构造一个纯函数,我们立即就会获取很多强大的技能。事实上,你可以做用F#做所有的事:
当用在编程的时候,数学函数也有一些看起来不是很好的特性。
这些特性也反映在函数式编程语言上,让我们一个个的看看:
不可变的值在理论上不错的想法,但在实际上如果你不能以传统的方式分配给变量,你怎么能完成工作?
我可以向你保证,这不是像你想的那个问题。当你通过这一系列的学习,你会看到在实践中是如何工作的。
像你看到的图解那样,数学函数总是只有存在一个输入和一个输出。这对于函数式编程语言也是的,尽管当你第一次用它的时候可能还不明显。
这看起来像是一个大烦恼。没有函数有两个(或者更多)参数你怎么做有用的事情?
当然,它变化了,有一个方法可以解决它,而且在F#中是完全透明的。它叫做“柯里化”,会很快出现在接下来的文章中。
事实上,你晚些就会发现,这两个没有用的特性变得非常的有用,而且这也是使函数式编程很强大的关键。
翻译有误,请指正,谢谢!
原文地址:http://fsharpforfunandprofit.com/posts/mathematical-functions/
原文:http://www.cnblogs.com/JayWist/p/5847761.html