?数学函数——在函数式编程背后的动力

函数式思维的动力来自数学。数学函数有很多特色——函数式语言试图模拟真实世界。

所以一开始,我们以一个加1函数开始:

Add1(x) = x+1

这意思是什么?好吧,看起来十分直白。它意味着有一个操作以一个数字开始,然后给它加1。

我们引入一些术语:

  • 可以被函数作为输入的值的集合叫做domain。这样,它可能是实数集合,为了简单,我们仅限于整数。
  • 可以被函数作为输出的值的集合叫做range(更科学的应该是叫作codomain的image)。还是仅限于整数。
  • 函数被称作映射domain到range。

在F#中,我们这样定义:

let add1 x = x + 1

如果你在F#交互窗口输入,你可以看到结果(函数的签名):

val add1 : int -> int

仔细看一下输出:

  • 大体意思是:函数add1将domain的整数映射到range中的整数
  • add1定义为val,value的简写。我们等一下再讨论value。
  • 箭头->用来展示domain和range。这里,domain是int类型,range是int类型。

注意类型不是特定的,F#编译器会猜测函数在使用int。

数学函数的关键属性

数学函数有很多属性和你在过程式编程用到的函数所不同。

  • 函数对于给的的输入值会给你相同的输出
  • 函数没有负面效应

这个数学提供了很多有力的好处,所以函数式编程语言在设计时也是试图加强这些属性。我们反过来挨个看它们。

函数对于给的的输入值会给你相同的输出

在命令式编程,我们认为函数做事情或者计算事情。数学函数没有做任何计算——它纯粹是将输入映射到输出。事实上,另一个方式思考定义一个函数是简单地作为所有映射的集合。例如,以一个非常生硬的方式这样定义add1函数(用C#):

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
   }
}

很明显,我们不能为每个可能的整数设置一个case,但是原理是一样的。你可以看到绝对没有一个计算,仅仅是一个遍历。

函数没有负面效应

在数学函数,输入和输出逻辑上是两个不同的东西,它们都是预先定义好的。函数没有改变输入和输出——它仅仅是从domain映射已经存在的输入值到range中的已经存在的输出值。

换句话说,函数没有可能在输入有任何的效应。函数没有实际计算或者操作什么,它仅仅是一个美化了的遍历。

值的不变性是微妙的但是十分重要。如果我在做计算,我不期望数字来改变它,当我将它们相加的时候。比如,如果我有:

x = 5
y = x+1

我不期望加1后,x被改变。我会期望得到一个不同的数字y,同时x没有被碰到。在数学的世界里,整数已经以一个无法改变的集合存在,add1函数仅仅定义了它们之间的关系。

pure函数的能力

这种函数有重复的结果,而且没有负面效应,我们称之为pure函数。你可以用它们做很多有意思的东西:

  • 它们是简单地并行的。我可以拿所有1到1000的整数,说,给定1000个不同的CPU,我可以使它们同时在对应的整数值来执行add1函数。这是安全的,因为它们之间没有必要有任何的交互。不需要锁,mutex,semaphore等。
  • 我可以懒惰地使用函数,只有当我需要输出地时候才执行它。我可以确定结果都会是一样的,不管我是现在执行还是稍后。
  • 我只需要为一个特定的输入执行一个函数,然后缓存结果,因为我知道了相同的输入总是对应相同的输出。
  • 如果我有很多pure函数,我可以以我喜欢的方式执行它们。再声明一遍,它不会改变最终结果。

你看到了如果我们可以创建函数式编程语言,我们可以立马得到很多厉害的技术。确实你可以用F#做这些事情。

数学函数的unhelpful属性

输入和输出不能变

理论上不变的值看起来是个好主意,但是如果你不能以传统方式给变量赋值你如何完成工作呢?

我确保你这不像你可能想的那样是个问题。当你看完这个系列,你就会看到实际中是如何解决的。

数学函数常常只有一个输入和输出

你从图表看到,数学函数常常只有一个输出。确实是这样,尽管当你第一次看到它们的时候没有那么明显。

看起来是个很大的烦恼。不用更多参数,如何能做有用的事情?

有一个方式来做,而且,F#中它是对你完全透明的。它叫做“currying”。

事实上,你会在后面发现,这两种“unhelpful”属性会证实是难以置信的有用——也是使得数学函数非常厉害的关键部分。

时间: 2024-10-28 15:38:25

?数学函数——在函数式编程背后的动力的相关文章

Python函数以及函数式编程

本文和大家分享的主要是python 函数及函数式编程相关内容,一起来看看吧,希望对大家 学习python有所帮助. 函数基本语法及特性 定义 数学函数定义: 一般的,在一个变化过程中,如果有两个变量 x 和 y ,并且对于 x 的每一 个确定的值, y都有唯一确定的值与其对应,那么我们就把 x 称为自变量,把 y 称为因变 量, y 是 x 的函数.自变量 x 的取值范围叫做这个函数的定义域. 但编程中的「函数」概念,与数学中的函数是有很  同的  函数是逻辑结构化和过程化的一种编程方法 函数的

python基础13函数以及函数式编程

主要内容 函数基本语法及特性 参数与局部变 返回值 4.递归 名函数 6.函数式编程介绍 阶函数 8.内置函数 函数基本语法及特性 定义 数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一 个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变 量,y是x的函数.自变量x的取值范围叫做这个函数的定义域. 但编程中的「函数」概念,与数学中的函数是有很 同的 函数是逻辑结构化和过程化的一种编程方法 函数的优点 减少重复代码 使程序变的可扩展 使程序

函数与函数式编程

函数与函数式编程 介绍 在过去的十年间,大家广为熟知的编程方法无非两种:面向对象和面向过程,其实,无论哪种,都是一种编程的规范或者是如何编程的方法论.而如今,一种更为古老的编程方式:函数式编程,以其不保存状态,不修改变量等特性重新进入人们的视野.下面我们就来依次了解这一传统的编程理念,让我们从基本的函数概念开始. 函数定义: 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的

Python之路Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数

Python之路Python作用域.匿名函数.函数式编程.map函数.filter函数.reduce函数 一.作用域 return 可以返回任意值例子 def test1(): print("test1") def test(): print("test") return test1 res = test() print(res) 输出结果 test <function test1 at 0x021F5C90> 分析:这里print(res)输出的是te

python 函数和函数式编程

什么是函数 调用函数 创建函数 传入函数 形参 变长参数 函数式编程 变量的作用域 递归 生成器 1 什么是函数 函数是对程序逻辑进行结构化或过程化的一种编程方法.能将整块代码巧妙地隔离成易于管理 的小块,把重复代码放到函数中而不是进行大量的拷贝--这样既能节省空间,也有助于保持一致性,因为你只需改变单个的拷贝而无须去寻找再修改大量复制代码的拷贝. 1.1 过程 vs 函数 在C++里我不记得有过程这种东西,但是在一些其它的语言比如PL/SQL里面会有过程.过程和函数一样是可以调用的代码块,但是

Python核心编程读笔 9:函数和函数式编程

第11章 函数和函数式编程 一 调用函数 1 关键字参数 def foo(x): foo_suite # presumably does some processing with 'x' 标准调用 foo(): foo(42)  foo('bar')  foo(y) 关键字调用 foo(): foo(x=42)  foo(x='bar')  foo(x=y) 即明确给出相应的参数名 2 参数组 Python允许程序员执行一个没有显式定义参数的函数,相应的方法是通过一个把元组(非关键字参数)或字典

Python基础函数之函数式编程

一. 匿名函数 匿名函数就是不需要显示的指定函数,只要运行过一次后就立马释放内存空间. 主要表现形式为: lambda 形参:具体功能 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc = lambda n:n**n print(calc(10)) 你也许会说,用上这个东西没感觉有毛方便呀, ....呵呵,如果是这么用,确实没毛线改进,不过匿名函数主要是和其它函数搭配使用的呢,如下 res = map(lambda x:x**2,[1,5

11 函数和函数式编程 - 《Python 核心编程》

?? 什么是函数 ?? 调用函数 ?? 创建函数 ?? 传入函数 ?? 形参 ?? 变长参数 ?? 函数式编程 ?? 变量的作用域 ?? 递归 ?? 生成器 11.1 什么是函数? 函数是对程序逻辑进行结构化或过程化的一种编程方法. 函数可以以不同的形式出现. declaration/definition          def foo(): print 'bar' function object/reference    foo function call/invocation      

《Python核心编程》第十一章:函数和函数式编程

本章大纲 介绍函数的创建.调用方式,内部函数.函数装饰器.函数参数的定义和传递.函数式编程.变量作用域.闭包. 知识点 11.1 什么是函数? 函数是对程序逻辑进行结构化或过程化的一种编程方法,以实现代码的复用. python 的过程就是函数,因为解释器会隐式地返回默认值 None. python 动态地确定函数返回类型,而不是进行直接的类型关联. 可以使用 type() 函数作为代理,处理有不同参数类型的函数的多重声明,以模拟其他编程语言的函数重载. 11.2 调用函数 11.2.1 关键字参