F#学习之路(2) 深刻理解函数(上)

函数在函数式编程语言中是一等公民,是函数式语言中最重要的基本组成元素,也是其名称的由来。

F# 中的函数之如C#中的类,是组织程序结构的最基本单元。是命令式编程语言中函数或OO编程语言中方法的超集。超集,有多强大?我将在下面几个方面细细道来。

F#是一种多范式的编程语言。支持命令式、函数式、面向对象的编程范式,还有目前火热的面向语言编程(DSL)。本文不会介绍其他的编程范式,只介绍函数式编程范式。

在面向对象编程的世界里,视命令式或过程式是一种丑陋的编程方式,至少被大多数程序员视为不能有效发挥OO语言强大功效的编程方法。在函数式编程世界里,同样会认为命令式、OO的编程范式只是辅助的编程方法。过程式的流程控制语句被认为是不适宜的,if else 的条件判断被替代为模范匹配,while,for的循环语句也替代为使用尾递归的递归函数。尽管F#支持其他两种编程范式,但还是应限定在特定的场景下,应主要以函数式编程范式为主,我将在以后专门写一篇blog来探讨F#中各种编程范式相应的适用场合。

本文假设已经使用了#light指令,下面的代码风格都是轻量的。注意#light指令要求你严格的缩进,空格被视为语法的一部分,同一层级的语句之间必须严格的对齐。为了方便的缩进,请设置tab为插入空格代替,我在前文 《F#学习之路 (1)什么是函数式编程》已有介绍设置的方法。

1、如何定义一个普通函数

F#中函数分为递归函数和非递归函数,我把非递归函数称为普通函数。F#中函数默认是不能递归的。

代码一:

Code

1   let f0 () =25
2
3   let f1 x =x+1
4
5   let f11 _ =1/0
6
7   let f2 x y=x+y
8
9   let f3 (x:float) (y:float) (z:float):string =sprintf "%f" ( x*y*z)
10
11   let isEven =fun x -> x %2=0
12
13   let fn f x=
14
15     match isEven x with
16
17     | true -> f(x)
18
19     | false ->()
20
21   let print_even x= fn ( fun x -> printfn "%d is even" x) x
22
23   print_even 20
24
25

上面的代码,你能够全部读懂吗?。

在F#中一切皆是表达式,记得这一点非常重要。这不同于命令式编程范式有语句概念。

什么是表达式,从学习c语言开始,给我灌输的概念是,表达式由运算符、常量、变量组成,表达运算产生结果值。我仍沿用这个概念,不过这个运算符、常量、变量有了新变化 。运算符是函数,大多数运算符允许你重新定义。默认定义的标识符是常量,不可变,变量使用mutable关键字指定。函数是表达式,lambda(可理解为匿名函数)是表达式,就连过程式的if else也是表达式,有运算结果值。需要指出的是在F#中,函数的返回值是由最后一个表达式计算的结果值,并且不能使用return 关键字指定。在循环结构while,for中也不能使用return。break目前版本用做保留关键字,return只能用做工作流中(一种使用monad算子的语法糖,我将在后面简述),while,for 表达式的结果值为(),()为Unit类型的实例,相当于C系列的void。因为没有了return,break,在F#中过程式的代码控制能力是受限的,要编写break,return的语义,你需要借助闭包和递归函数,所以你还是转变一下思维吧。

时间: 2024-09-09 05:22:35

F#学习之路(2) 深刻理解函数(上)的相关文章

F#学习之路(2) 深刻理解函数(下)

3.函数作用域 在F#中组织程序结构的方法有以下几种,使用类型 (type)来支持自定义数据类型,使用名称空间(namespace)来确保类型唯一,模块(module)则用来封装某一数据类型及其操作,而函数则封装了行为或业务逻辑.本文只简单介绍模块(module),其他内容将在下一主题中讨论. 函数是函数式语言中最基本的组成,是应用程序中具体业务逻辑的实现者,弄清其作用域非常必要. 在F#语言中,每一个源代码文件(本文仅指以.fs为扩展名的文件),其默认有一个以文件名首字母大写的模块名(modu

学习Flash AS之深入理解函数

函数 ◆理解函数的目的◆给函数传递参数◆理解函数的变量作用域的重要性◆编写自定义函数◆从函数返回值◆用setInterval()创建递归函数通过使用函数,就可以创建可重用的代码.可读的代码.灵巧的代码.有了函数,就可以写出有效的.结构精巧的.维护得很好的代码,而不是冗长的.笨拙的代码.一.理解用函数进行编程函数是一种革新.写代码没有函数,就像出版图书没有印刷机,出版业是如此没有生产力,如此没产量.有了印刷机,只制一次版,就可以从那个版复制出许多副本了.印刷机是一种革新.同样地,如果编程序没有函数

F#学习之路(6) 列表类型

列表在函数式编程中占据着重要的位置.在Lisp语言中,一切皆是列表,就连函数也是列表,列表在Lisp语言中发挥到了极致.F#语言列表语法来源于Ocaml,与Haskell语言也基本一致.本文只会讲解一些常用的使用方法,要很好的掌握列表,各位朋友可以google一下相关的内容.网络上对列表讨论比较深刻的大多以Haskell语言为例(Lisp语言列表很强大,但与大多数函数式语言列表的区别太大,不好借鉴). 一.如何定义列表 在F#中定义一个列表,有几个方法. 1.使用字量值 let l=[1;2;3

F#学习之路(5) 元组类型

元组类型,表示一组有序数据类型的集合.F#通过支持元组类型,方便了我们定义临时数据结构,而不需要为了临时的数据专门定义一个数据类型. 一.元组的定义: let tuple_2=(1,2) let tuple_3=("F#",1.9,"F# Function Language") 在F#中元组使用小括号,元素之间逗号分隔来定义.元组元素可以是任何类型. 上面代码中,tuple_2的类型是int*int,而tuple_3的类型为string*float*string.元

F#学习之路(1)什么是函数式编程

对于什么是函数式编程,这个是人云亦云.本文并不打算对此进行定义,而是希望与园子里的朋友们共同探讨这个话题,抛砖只为引玉. 1.维基百科给出的定义是: 函数式编程是种编程范式,它将电脑运算视为函数的计算.函数编程语言最重要的基础是λ 演算(lambda calculus). 而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值). 2.函数应该是高阶函数,可柯里化 从维基百科定义可以看出,大家对函数式编程语言中,函数是一等公民(first class)这个概念是没有异议的. 函数应该享受值的

王亟亟的Python学习之路(10)-函数对象的作用域,函数作为返回值,闭包

转载请注明出处:王亟亟的大牛之路 本来打算把工作的事周末做掉点,但是发现在外面浪并不能迅速集中投入,为了避免不必要的BUG 还是明天在家做吧,那么久写一篇Python的文章吧,毕竟背着Mac出门不做些太对不起自己的肩膀了 废话不多,直接说内容,这篇文章的内容大致是围绕"闭包"走的,介绍下相关理论知识 作用域:对象有其存活的范围 闭包:内部函数可以引用外部函数的参数和局部变量(是不是听得云里雾里的,没事 看例子就明白了) 就像循环内声明的对象,除了循环也就无法获取他的值一样.就像在jav

F#学习之路(7) 集合类型

上一篇博客,介绍了列表类型,本篇将介绍数组类型Array.字典类型(Map),以及可变数组(ResizeArray).Set类型. 一.数组类型 (Array) 数组类型,在语义上表示一组相同类型的集合.这个跟列表(List)相似,两者的区别在于列表类型数据元素不可变,而数组类型可以.虽然数组类型随机访问,在查询访问上性能优先列表,但列表在变更集合(增加.删除集合元素)上有更好的性能.这个跟大多数语言是相似的. 定义数组类型的语法,跟列表也很相似,区别在于数组多了两个"|"符合. le

F#学习之路(4) 基本类型

F#基本类型包括整型.浮点型.布尔型(bool).字符型(char).字符串型(string),还有元组类型(tuple).列表类型(list).数组类型(array),序列类型(seq).另外,还允许我们定义记录类型(record type).联合类型(union type).活动模式等.当然,F#作为一种多范式的编程语言,支持所有的OO编程语法,允许我们定义类.接口.委托.结构等,本篇文章只介绍基本类型,其它类型在后续的文章中一一介绍. 上面这张图,比较的详细的介绍了F#的基本类型.左边一列

Qt学习之路(7):创建一个对话框(上)

首先说明一点,在C++ GUI Programming with Qt4, 2nd中,这一章连同以后的若干章一起,完成了一个比较完整的程序--一个模仿Excel的电子表格.不过这个程序挺大的,而且书中也没有给出完整的源代码,只是分段分段的--我不喜欢这个样子,我想要看到我写出来的是什么东西,这是最主要的,而不是慢慢的过上几章的内容才能看到自己的作品.所以,我打算换一种方式,每章只给出简单的知识,但是每章都能够运行出东西来.好了,扯完了,下面开始! 以前说的主要是一些基础知识,现在我们来真正做一个