函数式编程

什么是函数式编程

``````# let double x = x * 2 in
List.map double [ 1; 2; 3 ];;- : int list = [2; 4; 6]
``````

`map`被称为高阶函数（higher-order function） (HOF)。高阶函数是指一个把其他函数作为参数之一的函数。

``````# let multiply n list =
let f x =
n * x in
List.map f list;;val multiply : int -> int list -> int list = <fun>
``````

``````# multiply 2 [1; 2; 3];;- : int list = [2; 4; 6]
# multiply 5 [1; 2; 3];;- : int list = [5; 10; 15]
``````

`map` 的定义在`List`模块中，离当前的代码很远。也就是说，我们把`f` 传递到一个”很久很久以前，在一个很遥远很遥远的星系“（译者：星球大战片头）中的一个模块。 代码可以传递`f`给其他模块，或者把它的引用（reference）在某个地方以便之后 再调用它。不管怎样，这个闭包保证`f`总是可以获取它定义时的环境，比如`n`

``````class html_skel obj = object (self)
...
...
method save_to_channel chan =
let receiver_fn content =
output_string chan content;
true in
save obj receiver_fn
...
end``````

部分函数应用（Partial function applications）和 currying（科里化）

``````# let plus a b =
a + b;;val plus : int -> int -> int = <fun>
``````

1. 什么是`plus`?
2. 什么是`plus 2 3`?
3. 什么是`plus 2`?

``plus : int -> int -> int``

``5 : int``

``````# plus 2;;- : int -> int = <fun>
``````

``````# let f = plus 2;;val f : int -> int = <fun>
# f 10;;- : int = 12
# f 15;;- : int = 17
# f 99;;- : int = 101
``````

``````let plus 2 b =       (* 这不是真正的OCaml代码！ *)
2 + b``````

``````    plus : int -> int -> int
plus 2 : int -> int
plus 2 3 : int``````

``````# let multiply n list =
let f x =
n * x in
List.map f list;;val multiply : int -> int list -> int list = <fun>
``````

``````# let double = multiply 2;;val double : int list -> int list = <fun>
# let triple = multiply 3;;val triple : int list -> int list = <fun>
``````

``````# double [1; 2; 3];;- : int list = [2; 4; 6]
# triple [1; 2; 3];;- : int list = [3; 6; 9]
``````

``````# let multiply n = List.map (( * ) n);;val multiply : int -> int list -> int list = <fun>
# let double = multiply 2;;val double : int list -> int list = <fun>
# let triple = multiply 3;;val triple : int list -> int list = <fun>
# double [1; 2; 3];;- : int list = [2; 4; 6]
# triple [1; 2; 3];;- : int list = [3; 6; 9]
``````

``````# let plus = ( + );;val plus : int -> int -> int = <fun>
# plus 2 3;;- : int = 5
``````

``````# List.map (plus 2) [1; 2; 3];;- : int list = [3; 4; 5]
# let list_of_functions = List.map plus [1; 2; 3];;val list_of_functions : (int -> int) list = [<fun>; <fun>; <fun>]
``````

纯函数式和非纯函数式编程

ML衍生的语言，如OCaml是“几乎纯”的。它们允许引用和数组引入一定的副作用，但很大程度上 你会写纯函数，而语言本身也鼓励你这么做。另一个函数式语言Haskell是纯的（如果不考虑IO模块）。 相比，OCaml更加实用，因为非纯的函数有时候还是很有用的。

``````for (i = 0; i < strlen (s); ++i)
{
// Do something which doesn't affect s.
}``````

非懒惰和懒惰

C类和ML类的语言都是非懒惰的（饥饿求值），而Haskell和Miranda都是懒惰的。OCaml是缺省非懒惰， 但是在需要的时候支持懒惰的风格。

``````# let give_me_a_three _ = 3;;val give_me_a_three : 'a -> int = <fun>
# give_me_a_three (1/0);;Exception: Division_by_zero.
``````

OCaml是一个非懒惰的语言，但是`Lazy`模块允许你写懒惰的表达式，下面就是这样一个例子：

``````# let lazy_expr = lazy (1/0);;val lazy_expr : int lazy_t = <lazy>
``````

``````# give_me_a_three lazy_expr;;- : int = 3
``````

``````# Lazy.force lazy_expr;;Exception: Division_by_zero.
``````

box和unbox类型

``````#include <stdio.h>

void
printit (int *ptr)
{
printf ("the number is %d\n", *ptr);
}

void
main ()
{
int a = 3;
int *p = &a;

printit (p);
}``````

`a`是在栈上的，显然是unboxed的。