我们在许多编程语言中都能看到一些函数式编程,其最初起源于大学实验室、数学推理的思想,虽然在目前大型软件的源代码中相对OOP编程并没有那么多,但是在一些核心数据处理中利用函数式编程能一定程度上保证程序正确性.这里使用ocaml.org学习函数式编程.
相对来说,ocaml,elixir,scala以及clojure等在工业界用得比其他语言要多一点,主要原因个人认为还是对于大数据、多线程的处理以及语法上的可读性. 学习这些语言能帮助扩展思维以及在其他现代的编程语言中,你很可能会看见类似的设计和思想.
函数式语言的设计往往非常优雅严谨,以此达到编写正确优美的代码.下面以ocaml作介绍.
表达式
OCaml语法的主要部分是表达式。就像命令式语言中的程序主要由命令构建一样,函数式语言中的程序主要由表达式构建。表达式的例子包括2+2和increment 21
在函数式语言中,计算的主要任务是将表达式求值为一个值。值是一个表达式,它不需要执行任何计算。所以,所有的值都是表达式,但不是所有的表达式都是值。值的例子包括2、true和”yay!”
Assertions
表达式assert e求e的值。如果结果为真,则不再发生任何事情,整个表达式的求值为一个名为unit的特殊值。unit写作(),类型为unit。但如果结果为false,则会引发异常。1
2
3let () = assert (f input1 = output1)
let () = assert (f input2 = output2)
let () = assert (f input3 = output3)
if表达式
1 | if 3 + 5 > 2 then "yay!" else "boo!" |
let表达式
1 | let x = 42 in x + 1 |
注意let x = 42;;
是定义而不是表达式
函数
1 | (** [fact n] is [n!]. |
pipeline
1 | square (inc 5);; |
高阶函数
这是在其他编程语言中非常常见的,包括map,filter,fold等等操作1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20(** [add1 lst] adds 1 to each element of [lst]. *)
let rec add1 = function
| [] -> []
| h :: t -> (h + 1) :: add1 t
let lst1 = add1 [1; 2; 3]
let rec map f = function
| [] -> []
| h :: t -> f h :: map f t
(** [add1 lst] adds 1 to each element of [lst]. *)
let add1 = map (fun x -> x + 1)
(** [concat_bang lst] concatenates "!" to each element of [lst]. *)
let concat_bang = map (fun x -> x ^ "!")
let p x = print_int x; print_newline(); x + 1
let lst = map p [1; 2]1
2
3let rec filter p = function
| [] -> []
| h :: t -> if p h then h :: filter p t else filter p t1
2
3
4
5let rec combine op init = function
| [] -> init
| h::t -> op h (combine op init t)
let sum = combine ( + ) 0
let concat = combine (^) ""
primitive types和values
基本类型是内置的和最基本的类型:整数、浮点数、字符、字符串和布尔值。它们将被识别为类似于其他编程语言中的基本类型.
除了上面之外,Ocaml还有许多东西,但我也就止于此了.目前我主要关注的还高阶函数