OCaml utop 清屏;有时候使用交互式解释器utop,有强迫症,想清屏;那就用如下命令, 最好用CTRL + L
utop # Sys.command "clear";;
很显然就是调用了clear命令; 例如:
utop # Sys.command "cal";;
二月 2022
日 一 二 三 四 五 六
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28
- : int = 0
元组(Tuple)是 可能不同类型
固定长度
的笛卡尔积
列表(List)是相同类型
任意长度
的结构
元组用,
分隔, 列表用;
分隔
注意下面, 列表内元素是 ;
隔开的
utop # let languages = ["C", "C++", 1];;
val languages : (string * string * int) list = [("C", "C++", 1)]
utop # let numbers = [3;"four";5];;
Error: This expression has type string but an expression was expected of type
int
下面是等价的:
utop # "C", "C++", 1;;
- : string * string * int = ("C", "C++", 1)
utop # ("C", "C++", 1);;
- : string * string * int = ("C", "C++", 1)
utop # let tuple = ("C", "C++", 1);;
val tuple : string * string * int = ("C", "C++", 1)
utop # let (x, y, z) = "C", "C++", 1;;
val x : string = "C"
val y : string = "C++"
val z : int = 1
let expression 其实就是匿名函数调用的语法糖;
let x = e1 in e2
等效于 (fun x -> e2) e1;
等效于 e1 |> (fun x -> e2)
utop # let x = 1 in x + 1;;
- : int = 2
utop # (fun x -> x + 1) 1;;
- : int = 2
utop # 1 |> fun x -> x + 1;;
- : int = 2
函数参数标记(Labeled)
与 可选(Optional)
函数参数:
utop # let a_cat_b ~a:x ~b:y = x ^ y;;
val a_cat_b : a:string -> b:string -> string = <fun>
utop # a_cat_b "1" "2";;
- : string = "12"
utop # a_cat_b ~a:"1" ~b:"2";;
- : string = "12"
utop # a_cat_b ~b:"1" ~a:"2";;
- : string = "21"
```shell
utop # let plus ?a:(x=10) ~b:y = x + y;;
val plus : ?a:int -> b:int -> int = <fun>
utop # plus 10;;
- : int = 20
utop # plus ~a:10 ~b:2;;
- : int = 12
下面函数等效:
utop # let add x y = x + y
utop # let add x = fun y -> x + y
utop # let add = fun x -> (fun y -> x + y)
val add : int -> int -> int = <fun>
这说明函数类型是右结合的:
t1 -> t2 -> t3 -> t4
等价 t1 -> (t2 -> (t3 -> t4))
另一方面,函数调用(function apply)则是左结合的
e1 e2 e3 e4
等价((e1 e2) e3) e4
操作符(任何内置操作符
)作为一个函数;
utop # (+);;
- : int -> int -> int = <fun>
utop # (+) 1 2;;
- : int = 3
utop # 1 + 2;;
- : int = 3
定义一个操作符(函数):
utop # let ( ^^ ) x y = max x y;;
val ( ^^ ) : 'a -> 'a -> 'a = <fun>
utop # 1 ^^ 2;;
- : int = 2
函数式编程注意尾递归优化: 4步走
- 添加一个helper function
helper
, 它的参数列表在原始函数(origin
)参数列表上加个累加器参数 (origin a b c -->. helper a b c acc
) - 假设原递归函数的
基本情况(递归终止判断后的返回值)
返回值为base, 对原函数重写新函数(origin_new)origin_new a b c = helper a b c base
main函数怎么用:original_new a b c
即可 - helper函数对于
基本情况
,返回acc - helper函数对于
递归情况
,在递归调用的累加器参数传参上做手脚
下面两个函数等效,后者称为立即匹配(Immediate Matches)
utop # let rec sum list =
match list with
| [] -> 0
| hd :: tl -> hd + sum tl;;
val sum : int list -> int = <fun>
utop # sum [1];;
- : int = 1
utop # sum [1; 2; 3];;
- : int = 6
utop # let rec sum = function
| [] -> 0
| hd :: tl -> hd + sum tl;;
val sum : int list -> int = <fun>
utop # sum [3];;
- : int = 3
utop # sum [1; 3; 4];;
- : int = 8
注意,立即匹配不需要函数参数,function为关键字。