撰写于2025年08月28日。
在简单探索之后,简单写一下成果。
环境配置
哎,这边直接用的Gleam Playground跑的,Gleam版本是1.12.0。
源码
import gleam/int
import gleam/io
const num: Int = 40
pub fn main() {
// tail recursion
fib1(num) |> int.to_string |> io.println
let fib2_anon = func3(fn (f1, f2, n, f) {
case n {
0 -> f1
_ -> f(f2, f1+f2, n-1)
}
})
let fib2 = fn (n) { fib2_anon(0, 1, n) }
// fixed-point combinator used, without currying; recursion may be too much
fib2(num) |> int.to_string |> io.println
let fib3_anon = fn (f) { fn (f1) { fn (f2) { fn (n) {
case n {
0 -> f1
_ -> f(f2)(f1+f2)(n-1)
}
}}}}
let fib3 = fix(fib3_anon)(0)(1)
// fixed-point combinator used, with currying; recursion may be too much
fib3(num) |> int.to_string |> io.println
}
pub fn fib1(n) {
fib1_loop(0, 1, n)
}
fn fib1_loop(f1, f2, n) {
case n {
0 -> f1
_ -> fib1_loop(f2, f1+f2, n-1)
}
}
// https://github.com/Olian04/gleam_recursive/blob/main/src/recursive.gleam
pub fn func3(cb) {
rec(fn(f) { fn(a, b, c) { cb(a, b, c, fn(a, b, c) { cb(a, b, c, f()) }) } })
}
// https://github.com/Olian04/gleam_recursive/blob/main/src/recursive.gleam
fn rec(f) {
f(fn() { rec(f) })
}
pub fn fix(f) {
f(fn (x) { fix(f)(x) })
}后记
fib2那边调用的func3和rec直接复制粘贴了gleam_recursive这边的源码,毕竟自己写可就烧脑了。
fib2和fib3均有递归过多的风险。fib3能稍微扛得住更大的num,不过还是谨慎为妙吧。
参考文章: