Packages

User friendly Fixed-point combinator functions. Any block or anonymous function can run recursively!

Current section

Files

Jump to
recursive src recursive.gleam
Raw

src/recursive.gleam

/// Raw fixed-point combinator.
/// Not intended to be used standalone
pub fn rec(f) {
f(fn() { rec(f) })
}
/// Fixed-point combinator.
/// Allows anonymous functions to run recursively
/// ```gleam
/// let factorial = recursive.fix(fn (it, f) {
/// case it {
/// 0 -> 1
/// 1 -> 1
/// _ -> it * f(it - 1)
/// }
/// })
/// io.debug(factorial(10))
/// ```
pub fn fix(cb) {
rec(fn(f) { fn(a) { cb(a, cb(_, f())) } })
}
/// Two argument Fixed-point combinator.
/// Allows anonymous functions to run recursively
/// ```gleam
/// let factorial = recursive.fix2(fn (it, res, f) {
/// case it {
/// 0 -> res
/// 1 -> res
/// _ -> f(it - 1, res * it)
/// }
/// })
/// io.debug(factorial(10, 1))
/// ```
pub fn fix2(cb) {
rec(fn(f) { fn(a, b) { cb(a, b, fn(a, b) { cb(a, b, f()) }) } })
}
/// Three argument Fixed-point combinator.
/// Allows anonymous functions to run recursively
/// ```gleam
/// let fibonacci = recursive.fix3(fn (it, curr, prev, f) {
/// case it {
/// 0 -> curr
/// _ -> f(it - 1, curr + prev, curr)
/// }
/// })
/// io.debug(fibonacci(9, 1, 0))
/// ```
pub fn fix3(cb) {
rec(fn(f) { fn(a, b, c) { cb(a, b, c, fn(a, b, c) { cb(a, b, c, f()) }) } })
}
/// Four argument Fixed-point combinator.
/// Allows anonymous functions to run recursively
pub fn fix4(cb) {
rec(fn(f) {
fn(a, b, c, d) { cb(a, b, c, d, fn(a, b, c, d) { cb(a, b, c, d, f()) }) }
})
}
/// Five argument Fixed-point combinator.
/// Allows anonymous functions to run recursively
pub fn fix5(cb) {
rec(fn(f) {
fn(a, b, c, d, e) {
cb(a, b, c, d, e, fn(a, b, c, d, e) { cb(a, b, c, d, e, f()) })
}
})
}
/// Usable Fixed-point combinator.
/// Allows any block to run recursively
/// ```gleam
/// // Factorial
/// io.debug({
/// use it, f <- recursive.use_fix(10)
/// case it {
/// 0 -> 1
/// 1 -> 1
/// _ -> it * f(it - 1)
/// }
/// })
/// ```
pub fn use_fix(initial, cb) {
fix(cb)(initial)
}
/// Two argument Fixed-point combinator.
/// Allows any block to run recursively
/// ```gleam
/// // Tail recursive factorial
/// io.debug({
/// use it, res, f <- recursive.use_fix2(10, 1)
/// case it {
/// 0 -> res
/// 1 -> res
/// _ -> f(it - 1, res * it)
/// }
/// })
/// ```
pub fn use_fix2(a, b, cb) {
fix2(cb)(a, b)
}
/// Three argument Fixed-point combinator.
/// Allows any block to run recursively
/// ```gleam
/// // Fibonacci
/// io.debug({
/// use it, curr, prev, f <- recursive.use_fix3(9, 1, 0)
/// case it {
/// 0 -> curr
/// _ -> f(it - 1, curr + prev, curr)
/// }
/// })
/// ```
pub fn use_fix3(a, b, c, cb) {
fix3(cb)(a, b, c)
}
/// Four argument Fixed-point combinator.
/// Allows any block to run recursively
pub fn use_fix4(a, b, c, d, cb) {
fix4(cb)(a, b, c, d)
}
/// Five argument Fixed-point combinator.
/// Allows any block to run recursively
pub fn use_fix5(a, b, c, d, e, cb) {
fix5(cb)(a, b, c, d, e)
}