对于什么是函数式编程,这个是人云亦云。本文并不打算对此进行定义,而是希望与园子里的朋友们共同探讨这个话题,抛砖只为引玉。
1、维基百科给出的定义是:
函数式编程是种编程范式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ 演算(lambda calculus)。
而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。
2、函数应该是高阶函数,可柯里化
从维基百科定义可以看出,大家对函数式编程语言中,函数是一等公民(first class)这个概念是没有异议的。
函数应该享受值的同等待遇,可以作为一个函数的参数,可以作为一个函数的返回值。
函数应该是高阶函数。函数应该可柯里化(currying)。
#light
letpf=
fun(x)-> f(x)
letct=
t+10
letr=pc
letf=p(funx->"Hello,"+x)
printfn"r=%d"(r10);
printfn"f=%s"(f"Lvxuwen")
openSystem
Console.ReadKey(true)
在F#中定义一个函数使用let 绑定表达式, 语法规则如下:
let函数名 参数1 参数2…参数n=函数体
F#参数之间用空格分隔,而不同于C#中用逗号分隔,参数也不用括号。
上面的F#代码第一行用#light指令,指出使用精简的语法规则,而不使用OCaml语法,OCaml语法使用begin end ;; ; in 等关键字来区分语句及作用域,使用#light指令后,虽然让我们可以使用简洁的语法,但这也意味着F#将利用缩进来区分语句及作用域。你可以在vss中 选择工具-选项-文本编辑器->F#-Tabs,设置Tab为插入空格,这可以让你方便的使用tab键缩进。另外,在vss中,你把上例"Hello," 改成中文"欢迎",如果在控制台中乱码,你可以选择 文件->高级保存选项->更改字符编码为中文简体GB2312或unicode编码。
3、纯函数式语言没有变量和副作用
这一点是函数式语言被认为编写并发程序最理想语言的重要原因。没有了变量和副作用,就不再有竞争资源的问题存在,就不再需要锁。
在F#中,let定义的标识符是表达式,并且一旦定义就不可更改。定义变量要使用专门的关键字mutable
letmutablevar=20
var<-30;
letconstant=30
constant=40
printfn"var=%d"var
printfn"constant=%d"constant
变量var使用mutable关键字定义,并使用<-操作符赋值。而=操作符而被用做相等比较运算符,而constant使用<-,就会编译报错
函数式编程中,函数用来定义规则,算法,如果一个函数使用同一个值传入,总是返回相等的结果,我们就说这个函数是没有副作用, 幂等的。 这样的函数最符合重用的原则,在高阶函数计算过程中可得到预知的结果。
4、函数式编程函数应该是惰性求值的
惰性求值(Lazy value),指的是表达式在需要时计算,而不是在定义时计算。这是支撑函数组合计算必要的条件,函数作为值传递过程中并不计算,只在明确调用时计算。
letla=lazy(printfn"%s""Helloworld";5)
[la;la]|>List.iter(funla->printfn"%d"(la.Force()))
某些函数式语言,会将一些惰性操作作为普通求值过程的一部分,而F#则需要使用lazy来明确指定,表达式求值是惰性的。
5、函数式编程中大量使用模式匹配
lett=true
matchtwith
true->printfn"itistrue"
|false->printfn"itisfalse"
6、函数式编程中经常使用递归来代替循环。
letrecloopnf=
matchfnwith
|true->n
|_->f(n-1)
总结:函数式编程语言中函数是一等公民,它使用高阶函数来组合函数,数据从函数中流入流出,函数式程序就是一个个函数的组合,数据被一个个函数处理, 或折分或组合生成新的数据结构。
版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明!