1 / 2
07 / 17 · Lists and Patterns
尾递归
递归调用如果是「做完才能返回」,栈会跟着列表长。
sum 在递归回来之后还要做加法,所以不是尾调用。列表一长,栈就深。
sum_tr 把还没加完的数放进 acc,递归调用就是整个函数体。编译器可以把这种调用收成循环。两种写法对短列表结果一样,差在大列表会不会爆栈。
例子
utop
let rec sum xs =
match xs with
| [] -> 0
| hd :: tl -> hd + sum tlval sum : int list -> int = <fun>
let rec sum_tr xs acc =
match xs with
| [] -> acc
| hd :: tl -> sum_tr tl (acc + hd)val sum_tr : int list -> int -> int = <fun>
sum [1; 2; 3; 4]- : int = 10
sum_tr [1; 2; 3; 4] 0- : int = 10
改一改
改完再跑
解释器覆盖书前半的核心:函数、标签参数、模式、记录、变体、ref、模块,以及简化的 Map 和 JSON。没有 GADT 细化、Async 和独立编译。
先预测,再对照
2 / 2