OCaml 速查表是 OCaml 编程语言的单页参考表。
注意:#
表示在顶层(toplevel)执行,后面是输出结果
# ();; (* 相当于 C 语言中的 void *)
- : unit = ()
# 5 ;; (* 整数 *)
- : int = 5
# 3.14 ;; (* 浮点数 *)
- : float = 3.14
# true ;; (* 布尔值 *)
- : bool = true
# false ;;
- : bool = false
# 'a' ;; (* 字符 *)
- : char = 'a'
# "一个字符串" ;; (* 字符串,将 "a string" 翻译为 "一个字符串" *)
- : string = "a string"
# String.to_bytes "你好" ;; (* 字节序列,将 "hello" 翻译为 "你好" *)
- : bytes = Bytes.of_string "hello"
# (3, 5);; (* 元组 *)
- : int * int = (3, 5)
# ref 0;; (* 引用 *)
- : int ref = {contents = 0}
# Some 42;;
- : int option = Some 42
# Ok 42;;
- : (int, 'a) result = Ok 42
# Error "404";;
- : ('a, int) result = Error 404
# [|0; 1; 2; 3|];; (* 创建一个数组 *)
- : int array = [|0; 1; 2; 3|]
# [|'u'; 's'; 'c'|].(1);; (* 数组访问 *)
- char = 's'
数组是可变的
let scores = [|97; 85; 99|];;
- : int array = [|97; 85; 99|]
# scores.(2) <- 89;; (* 更新一个元素 *)
- unit = ()
# scores;;
- : int array = [|97; 85; 89|]
# [1; 2; 3];;
- : int list = [1; 2; 3;]
# ["a"; "字符串"; "列表"];; (* 将 "str" 和 "lst" 翻译为 "字符串" 和 "列表" *)
- : string list = ["a"; "str"; "lst"]
列表是不可变的
# let lst = [1; 2; 3];;
- : int list = [1; 2; 3]
# let new_lst = 0 :: lst;; (* 前置元素到新列表 *)
- : int list = [0; 1; 2; 3]
# new_lst @ [4;5;6];; (* 合并两个列表 *)
- : int list = [0; 1; 2; 3; 4; 5; 6]
捆绑相关数据
type person = {
name: string;
age: int
}
# let zeno = {name = "芝诺"; age = 30};; (* 将 "Zeno" 翻译为 "芝诺" *)
val zeno : person = {name = "Zeno"; age = 30}
几种不同但相关的类型
type shape =
| Circle of float
| Rectangle of float * float
# let my_shape = Circle 5.0;;
- : shape = Circle 5.
为复杂或常用的类型提供有意义的名称
type point = float * float
# let origin: point = (0.0, 0.0);;
val origin : point = (0., 0.)
let is_pos x =
if x > 0 then "正数" else "负数" (* 将 "positive" 和 "negative" 翻译为 "正数" 和 "负数" *)
let f x =
if x > 3 then "大于 3" (* "gt 3" -> "大于 3" *)
else if x < 3 then "小于 3" (* "lt 3" -> "小于 3" *)
else "等于 3" (* "eq 3" -> "等于 3" *)
####模式匹配
let is_pos x =
match x > 0 with
| true -> "正数" (* "positive" -> "正数" *)
| false -> "负数" (* "negative" -> "负数" *)
# let lst = [1; 2; 3];;
val lst : int list = [1; 2; 3]
# List.filter (fun x -> x mod 2 = 0) lst;;
- : int list = [2]
# List.find (fun x -> x = 4) lst;;
Exception: Not_found (* 异常:未找到 *)
# List.sort compare [2; 1; 3];;
- : int list = [1; 2; 3]
(* 遍历列表并应用函数 f *)
List.iter f lst
(* 将函数映射到每个元素 *)
(* 例如:将 lst 中的每个元素 x 加倍 *)
List.map (fun x -> x + x) lst
(* 在元素之间应用操作符 *)
(* 例如:1 + 2 + 3 *)
List.fold_left (+) 0 lst
let scores =
[("数学", 91); ("哲学", 89); ("统计", 94)] (* "math", "phil", "stats" -> "数学", "哲学", "统计" *)
# List.assoc "统计" scores;; (* "stats" -> "统计" *)
- : int = 94
# List.mem_assoc "数学" scores;; (* "math" -> "数学" *)
- : bool = true
# List.split scores;;
- : string list * int list = (["数学"; "哲学"; "统计"], [91; 89; 94]) (* "math"; "phil"; "stats" -> "数学"; "哲学"; "统计" *)
# List.combine [1;2;3] [4; 5; 6];;
- : (int * int) list = [(1, 4); (2, 5); (3, 6)]
关联列表类似于字典或哈希映射。
哈希表是可变的。
# let my_htable = Hashtbl.create 3;;
val my_htable : ('_weak1, '_weak2) Hashtbl.t = <abstr>
# Hashtbl.add my_htable "A" "约翰"; (* "John" -> "约翰" *)
Hashtbl.add my_htable "A" "简"; (* "Jane" -> "简" *)
Hashtbl.add my_htable "B" "麦克斯";; (* "Max" -> "麦克斯" *)
# Hashtbl.find my_htable "A";;
- : string = "简" (* "Jane" -> "简" *)
(* 查找所有 *)
# Hashtbl.find_all my_htable "A";;
- : string list = ["简"; "约翰"] (* "Jane"; "John" -> "简"; "约翰" *)
映射是不可变的键值关联表。
(* Map.Make 函子创建自定义映射模块 *)
# module StringMap = Map.Make(String);;
let books =
StringMap.empty
|> StringMap.add "沙丘" ("赫伯特", 1965) (* "Dune", "Herbet" -> "沙丘", "赫伯特" *)
|> StringMap.add "神经漫游者" ("吉布森", 1984) (* "Neuromancer", "Gibson" -> "神经漫游者", "吉布森" *)
(* find_opt 返回包装在 option 中的关联值,否则返回 None *)
# StringMap.find_opt "沙丘" books;; (* "Dune" -> "沙丘" *)
- : (string * int) option = Some ("赫伯特", 1965) (* "Herbet" -> "赫伯特" *)
(* find 返回关联值,否则抛出 Not_Found 异常 *)
# StringMap.find "沙丘" books;; (* "Dune" -> "沙丘" *)
- : string * int = ("赫伯特", 1965) (* "Herbet" -> "赫伯特" *)
创建一个新的映射,因为映射是不可变的。
let more_books = books
|> StringMap.add "基地" ("艾萨克·阿西莫夫", 1951) (* "Foundation", "Isaac Asimov" -> "基地", "艾萨克·阿西莫夫" *)
let less_books = books (* 修正:应为 books |> StringMap.remove "Dune" *)
|> StringMap.remove "沙丘" (* "Dune" -> "沙丘" *)
过滤
let eighties_books =
StringMap.filter
(fun _ (_, year) -> year > 1980 && year < 1990) books (* 修正:number 应为 year *)
let print_books map =
StringMap.iter (fun title (author, year) ->
Printf.printf "书名: %s, 作者: %s, 年份: %d\n" title author year (* "Title", "Author", "Year" -> "书名", "作者", "年份" *)
) map
# let () = print_books eighties_books;;
书名: 神经漫游者, 作者: 吉布森, 年份: 1984 (* "Title: Neuromancer, Author: Gibson, Year: 1984" -> "书名: 神经漫游者, 作者: 吉布森, 年份: 1984" *)