aiken_scott_utils/list

Utility functions for traversing lists while collecting more than one values.

Sample code to see how you can use one of the fold functions with the backpassing syntax:

use aiken_scott_utils/list as scott_list

fn avg_of_sums_and_products(xs: List<Int>) -> Int {
  let
    sum,
    product,
  <-
    scott_list.foldr2(
      xs,
      0,
      1,
      fn(x, sum_so_far, prod_so_far, return) {
        return(sum_so_far + x, prod_so_far * x)
      },
    ) 
  (sum + product) / 2
}

The same code without backpassing syntactic sugar:

use aiken_scott_utils/list as scott_list

fn avg_of_sums_and_products_desugared(xs: List<Int>) -> Int {
  scott_list.foldr2(
    xs,
    0,
    1,
    fn(x, sum_so_far, prod_so_far, return) {
      return(sum_so_far + x, prod_so_far * x)
    },
    fn(sum, product) { (sum + product) / 2 }
  ) 
}

Functions

foldl2(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  with: fn(x, a, b, Scott2<a, b, result>) -> result,
  return: Scott2<a, b, result>,
) -> result

foldr2(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  with: fn(x, a, b, Scott2<a, b, result>) -> result,
  return: Scott2<a, b, result>,
) -> result

foldl3(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  zero_c: c,
  with: fn(x, a, b, c, Scott3<a, b, c, result>) -> result,
  return: Scott3<a, b, c, result>,
) -> result

foldr3(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  zero_c: c,
  with: fn(x, a, b, c, Scott3<a, b, c, result>) -> result,
  return: Scott3<a, b, c, result>,
) -> result

foldl4(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  zero_c: c,
  zero_d: d,
  with: fn(x, a, b, c, d, Scott4<a, b, c, d, result>) -> result,
  return: Scott4<a, b, c, d, result>,
) -> result

foldr4(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  zero_c: c,
  zero_d: d,
  with: fn(x, a, b, c, d, Scott4<a, b, c, d, result>) -> result,
  return: Scott4<a, b, c, d, result>,
) -> result

foldl5(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  zero_c: c,
  zero_d: d,
  zero_e: e,
  with: fn(x, a, b, c, d, e, Scott5<a, b, c, d, e, result>) -> result,
  return: Scott5<a, b, c, d, e, result>,
) -> result

foldr5(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  zero_c: c,
  zero_d: d,
  zero_e: e,
  with: fn(x, a, b, c, d, e, Scott5<a, b, c, d, e, result>) -> result,
  return: Scott5<a, b, c, d, e, result>,
) -> result

foldl6(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  zero_c: c,
  zero_d: d,
  zero_e: e,
  zero_f: f,
  with: fn(x, a, b, c, d, e, f, Scott6<a, b, c, d, e, f, result>) -> result,
  return: Scott6<a, b, c, d, e, f, result>,
) -> result

foldr6(
  self: List<x>,
  zero_a: a,
  zero_b: b,
  zero_c: c,
  zero_d: d,
  zero_e: e,
  zero_f: f,
  with: fn(x, a, b, c, d, e, f, Scott6<a, b, c, d, e, f, result>) -> result,
  return: Scott6<a, b, c, d, e, f, result>,
) -> result

find2(
  self: List<x>,
  predicate_a: fn(x) -> Bool,
  predicate_b: fn(x) -> Bool,
  return: Scott2<Option<x>, Option<x>, result>,
) -> result

find3(
  self: List<x>,
  predicate_a: fn(x) -> Bool,
  predicate_b: fn(x) -> Bool,
  predicate_c: fn(x) -> Bool,
  return: Scott3<Option<x>, Option<x>, Option<x>, result>,
) -> result

find4(
  self: List<x>,
  predicate_a: fn(x) -> Bool,
  predicate_b: fn(x) -> Bool,
  predicate_c: fn(x) -> Bool,
  predicate_d: fn(x) -> Bool,
  return: Scott4<Option<x>, Option<x>, Option<x>, Option<x>, result>,
) -> result

find5(
  self: List<x>,
  predicate_a: fn(x) -> Bool,
  predicate_b: fn(x) -> Bool,
  predicate_c: fn(x) -> Bool,
  predicate_d: fn(x) -> Bool,
  predicate_e: fn(x) -> Bool,
  return: Scott5<Option<x>, Option<x>, Option<x>, Option<x>, Option<x>, result>,
) -> result

find6(
  self: List<x>,
  predicate_a: fn(x) -> Bool,
  predicate_b: fn(x) -> Bool,
  predicate_c: fn(x) -> Bool,
  predicate_d: fn(x) -> Bool,
  predicate_e: fn(x) -> Bool,
  predicate_f: fn(x) -> Bool,
  return: Scott6<
    Option<x>,
    Option<x>,
    Option<x>,
    Option<x>,
    Option<x>,
    Option<x>,
    result,
  >,
) -> result

at2(
  self: List<x>,
  index_a: Int,
  index_b: Int,
  return: Scott2<Option<x>, Option<x>, result>,
) -> result

Unit tests suggest using at2 is not very different from using list.at twice.

at3(
  self: List<x>,
  index_a: Int,
  index_b: Int,
  index_c: Int,
  return: Scott3<Option<x>, Option<x>, Option<x>, result>,
) -> result

Unit tests suggest using at3 is not very different from using list.at three times.

at4(
  self: List<x>,
  index_a: Int,
  index_b: Int,
  index_c: Int,
  index_d: Int,
  return: Scott4<Option<x>, Option<x>, Option<x>, Option<x>, result>,
) -> result

at4 and up are more performant than multiple calls to list.at.

at5(
  self: List<x>,
  index_a: Int,
  index_b: Int,
  index_c: Int,
  index_d: Int,
  index_e: Int,
  return: Scott5<Option<x>, Option<x>, Option<x>, Option<x>, Option<x>, result>,
) -> result

at6(
  self: List<x>,
  index_a: Int,
  index_b: Int,
  index_c: Int,
  index_d: Int,
  index_e: Int,
  index_f: Int,
  return: Scott6<
    Option<x>,
    Option<x>,
    Option<x>,
    Option<x>,
    Option<x>,
    Option<x>,
    result,
  >,
) -> result

Search Document