第一个函数式求和,从i到j求和,这里假定i是下限,j是上限
let rec sum i j =
if i > j then 0
else i + (sum (i+1) j) ;;
这个递归实现很简单,但是由于不是尾递归的,所以编译器不能转成迭代来计算,当递归层数太高
的情况下stack会溢出,稍微修改一下,可以改成递归版本
let sum i j =
let rec sum_int i j s =
if i > j then s
else sum_int (i+1) j (s+i)
in
sum_int i j 0 ;;
这里定义了一个sum_int的内部函数,他是一个尾递归的函数,编译器会转成迭代来计算。
这里简单求和看起来没啥用处,进一步我们可以推广到求和\sum_{k=i}^j f(k),只要简单修改
一下sum的定义,加入一个f的参数,可以得到
let sum f i j =
let rec sum_int f i j s =
if i > j then s
else sum_int f (i+1) j (s + f i)
in
sum_int f i j 0;;
这里可以看出,区间的遍历我们是使用+,结果的累积是使用+,空集对应的结果是0,这些其实可以进一步的泛化,
从而得到更加一般的求和。