当前位置: 首页>开发笔记>正文

函数式编程之根-拉姆达运算/演算(λ-calculus)

函数式编程之根-拉姆达运算/演算(λ-calculus)

0.1.6函数编程范式 】

1930s初,普林斯顿大学的逻辑学家阿伦佐·丘奇 (Alonzo Church,1903-1995) 开发出了一种新的形式系统(formal system),即拉姆达运算/演算 (λ-calculus 、lambda calculus ,lambda即希腊字母λ)。由于任何一个可计算函数都能用λ演算来表达和求值,它等价于图灵机。λ演算决定或形成了函数式编程范式。函数式语言的典型代表有Lisp、Scheme、ML、Haskell和Erlang等等,λ演算是函数式编程语言共同的祖先。

 ★函数编程范式的核心观念:以λ表达式构造一切。

什么是λ表达式呢?

普通的数学函数如f(x)=x+1,功能是给其参数x加上1。为了将数学函数表示成计算机程序中常用的表达式,可以换一种写法:λx.( x+1),读成“对于参数x,x+1”(假定操作符+已经被定义)。丘奇选择了λ,因此各种相关计算称为λ演算。Lambda,λ,仅仅表达的是数学"函数"的概念

λ表达式极其简洁,由变量、操作符(假定被定义)、两个抽象符号λ和.(即点),以及括号( )组成。合法的λ表达式的递归定义如下:

  • 变量(和文字)是一个λ表达式。
  • 操作符和λ表达式组成的表达式,是λ表达式。(可以纳入函数应用)
  • 函数定义和函数应用是λ表达式。

各种编程语言,也引入了λ表达式。例如:

C#语言:(x) =>{ return x+1; }

Java语言:(x) ->{ return x+1; }

Scheme语言:(lambda (x) (+ x 1))

1.“归根结底”的含义

使用λ演算,可以对编程的元素进行了全新的描述。例如布尔值、与或非操作的定义,数字的定义等等,如例程0-4所示。布尔值true可以定义为函数T,被描述为在一对值x和y中选择前者,函数T的应用如((T 1) 2)则输出1;数字,参考[5.1.2自然数和丘奇数]中丘奇数的介绍。

当说到“以λ表达式构造一切”这一函数编程范式的核心观念时,是一种“归根结底”的态度,就如同命令思维的人认为:编程语言中的一切元素,归根结底都是0和1。这种归根结底的方式,其实与程序员的日常思考有相当大的距离,因为程序员需要的是true和false的概念(Scheme语言中的#t、#f)、是布尔类型的值。

正如人们习惯了手机、钢笔、书籍、素菜等等东西,当有人说它们归根结底都是原子或波,人们的反应是给他一个大白眼。程序员应该对归根结底的底层知识有大概的了解——需要一开始就知道编程的元素全部由拉姆达运算定义,程序员真正常用的是各种“高级”概念——true和false、int数字等。SICP练习2.6写到:『如果觉得将序对表示为过程还不足以令人如雷灌顶,那么请考虑,在一个可以对过程做各类操作的语言中,我们完全可以没有数』。事实上,((T 1) 2)输出1比没有数更加令人如雷灌顶,对错之分被表示为一个选择函数,不足以令人惊讶吗?

;;;例程 0-4 核心观念远离程序员
;;; 归根结底.rkt
(define T  (lambda (x) (lambda (y) x))   ) ;;; true
((T 1) 2) ;;; 输出1.
(define F  (lambda (x) (lambda (y) y))   );;; false
(define And  (lambda (x) (lambda (y) (x y) F)   ))
((And T) F ) ;;;#<procedure:f> (> 3 2) ;;; 输出 #t,这才是程序员需要的

正如代码都会变成0和1,这和程序员编写C、Java等语言代码又有什么直接关系呢。

因此,当讨论函数编程范式时,通常讨论该范式体现在程序员们眼中的“特征”而非拉姆达运算的语法和语义。例如:

  • 数据的不变性。
  • 使用递归作为循环的机制。
  • 函数没有副作用和引用透明。参考[编程导论(Java )·3.1.2 方法]
  • 支持高阶函数(higher-order functions) 和闭包(closures)。参考[2.3高阶函数]
  • 支持惰性计算(lazy evaluation)。

2.学习函数式编程,从了解变量开始

3. 函数定义和函数应用

  •  函数抽象:W是参数为变量x的λ表达式,则λx.W是λ表达式。这种表达式给出了一个函数的定义:W是函数体,形参就是变量x。
    λx.( x+1)
    λx. λy. ( x+y) ;;;表示 λx. (λy. ( x+y))
  •  函数应用:有了f(x)=x+1,自然需要计算f(2),即给函数一个(实际)参数进行求值。A、B是λ表达式,则 (A B) 也是λ表达式,表示将实参B带入函数A中。

下面的内容,将作为学习函数式编程的大图(big map)/鸟瞰图,以便在学习过程中知道自己身在何处。

0.1.1 λ表达式

下面是一些λ表达式的例子:

最简单的:x、y、

函数抽象:λx.x、λx.y、

函数应用:(λx.x y)、(x y)、λx. (x y)……

2.函数定义的特点

  • 匿名函数。数学函数如f(x)=x+1或λ表达式如λx.( x+1),描述了一个计算过程;数学函数的f是函数名,而λ表达式关注计算过程,为该函数命名,变成了程序员的事情。
  • 每个函数只有一个输入参数,如λn. λm.λf.λx. ((n f)  (++ m) )。编程时函数通常可以有一个参数列表,逻辑学家 Haskell Curry证明可以将一个拥有多个参数的函数转化为只有一个参数的多个函数的连续调用,这一转化过程称为对拥有多个参数的函数的currying/柯里化
3.通过 丘奇数,熟悉 λ演算的α-变换和β简化。

https://www.zydui.com/af90dV28BAA8.html
>

相关文章:

  • matlab计算方程的根
  • 拉姆达表达式
  • 里兹法的求解步骤
  • 拉格朗日算法和欧拉算法
  • 茹科夫斯基函数
  • λ演算的书籍
  • λ运算
  • 高阶基函数的作用
  • vscode搭建nodejs環境,關于VS code ESP-IDF 提示“loading ‘build.ninja‘: 系統找不到指定的文件” 的解決方案
  • 什么是應用軟件并舉例,16.應用舉例
  • 【面經】美團春招三輪面經分享~涵蓋眾多知識點
  • 2021年面試題目,面試題--新增
  • magic king怎么讀,magick++ 簡介
  • 微信怎么設置定時發送,朋友圈可以定時發送嗎?
  • can not connect to rpc service,RPC service
  • ftpserver安卓版,FTPServer
  • server u使用教程,Server-U
  • rpc服務器,RPC 和 Web Service 有什么區別?
  • rpc服務器,web service和rpc的區別
  • psexec
  • dhclient命令,hpe?3par命令行查看狀況腳本
  • hp存儲默認管理口地址,HP3par 多路徑存儲磁盤使用方法
  • hp3par命令行手冊,3par命令集
  • 存儲器芯片的地址范圍,存儲器芯片類別有哪些?
  • 在pc機中各類存儲器,1.14各類存儲器芯片
  • 存儲芯片漲價最新消息,存儲器芯片
  • Windows/Linux性能監控軟件>csv文件,方便生成圖表
  • sqlserver nvarchar,【SQL開發實戰技巧】系列(四十五):Oracle12C常用新特性?VARCHAR2/NVARCHAR2類型最大長度由40
  • arcgis怎么導入地圖,Arcgis路網導入3dmax批量改成道路面
  • 定義animal父類,定義一個父類Animal eat方法 , 定義兩個子類 Dog 特有方法keepHome , Cat 特有方法 catchMouse ;并
  • 手機連接兩個藍牙方法,打開藍牙的設置
  • iconfont圖標免費嗎,關于阿里矢量圖標彩色icon使用
  • ps制作賽博朋克風格,如何用ps做出賽博朋克的風格?
  • ue4綠幕實時導入場景,如何在UE4中制作賽博朋克LED效果
  • 產品經理有哪些培訓課程,2023年全國NPDP產品經理國際認證火熱招生啦
  • B端產品需要什么能力,NPDP認證|B端產品經理是如何做競品調研的?
  • 超級工具,Supershell 一款牛叉閃閃的工具
  • buffer在c語言中是什么意思,QBuffer 用法理解