/* * Copyright 2019 Liam Palmer, Magnus Madsen * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */pubmod List {use Math.Shuffle////// The List type.////// A list is either the empty list represented by `Nil`, or/// an element `v` followed by a list `vs` represented by `v :: vs`.///pubenumList[t] {case Nilcase Cons(t, List[t]) }instanceFormattable[List[a]] withFormattable[a] {typeAef = Formattable.Aef[a]pubdefformat(x: List[a]): RichString \ Formattable.Aef[a] =RichString.fromString("List#{") +RichString.joinWith(Formattable.format, RichString.fromString(", "), x) +RichString.fromString("}") }instanceToString[List[a]] withToString[a] {pubdeftoString(l: List[a]): String = List.toString(l) }instanceHash[List[a]] withHash[a] {pubdefhash(l: List[a]): Int32 =List.foldLeft((acc, x) -> acc`Hash.combine`Hash.hash(x), Hash.magic(), l) }instanceEq[List[a]] withEq[a] {@Terminates@Tailrecpubdefeq(l1: List[a], l2: List[a]): Bool = match (l1, l2) {case (Nil, Nil) => truecase (x :: rs, y :: qs) => if (x!=y) falseelsers==qscase_ => false } }instanceOrder[List[a]] withOrder[a] {////// Compares `l1` and `l2` lexicographically.///@Terminates@Tailrecpubdefcompare(l1: List[a], l2: List[a]): Comparison = match (l1, l2) {case (_ :: _, Nil) => Comparison.GreaterThancase (Nil, Nil) => Comparison.EqualTocase (Nil, _ :: _) => Comparison.LessThancase (z :: zs, w :: ws) =>letcmp = z<=>w;if (cmp== Comparison.EqualTo) zs<=>wselsecmp } }instanceFunctor[List] {pubdefmap(f: a -> b \ ef, l: List[a]): List[b] \ ef = List.map(f, l) }instanceApplicative[List] {pubdefpoint(a: a): List[a] = List.point(a)pubdefap(f: List[a -> b \ ef], x: List[a]): List[b] \ ef = List.ap(f, x) }instanceMonad[List] {pubdefflatMap(f: a -> List[b] \ ef, x: List[a]): List[b] \ ef = List.flatMap(f, x) }instanceMonadZero[List] {pubdefempty(): List[a] = Nil }instanceMonadZip[List] {pubdefzipWith(f: (a, b) -> c \ ef, xs: List[a], ys: List[b]): List[c] \ ef = List.zipWith(f, xs, ys)pubdefzipWithA(f: (a, b) -> f[c] \ ef, xs: List[a], ys: List[b]): f[List[c]] \ efwithApplicative[f] = List.zipWithA(f, xs, ys) redef zip(xs: List[a], ys: List[b]): List[(a, b)] = List.zip(xs, ys) redef unzip(xs: List[(a, b)]): (List[a], List[b]) = List.unzip(xs) }instanceFoldable[List] {pubdeffoldLeft(f: (b, a) -> b \ ef, s: b, l: List[a]): b \ ef = List.foldLeft(f, s, l)pubdeffoldRight(f: (a, b) -> b \ ef, s: b, l: List[a]): b \ ef = List.foldRight(f, s, l) redef head(l: List[a]): Option[a] = List.head(l) redef isEmpty(l: List[a]): Bool = List.isEmpty(l) redef memberOf(x: a, l: List[a]): BoolwithEq[a] = List.memberOf(x, l) redef forAll(f: a -> Bool \ ef, l: List[a]): Bool \ ef = List.forAll(f, l) redef exists(f: a -> Bool \ ef, l: List[a]): Bool \ ef = List.exists(f, l) }instanceUnorderedFoldable[List] {pubdeffoldMap(f: a -> b \ ef, l: List[a]): b \ efwithCommutativeMonoid[b] = List.foldMap(f, l) redef isEmpty(l: List[a]): Bool = List.isEmpty(l) redef exists(f: a -> Bool \ ef, l: List[a]): Bool \ ef = List.exists(f, l) redef forAll(f: a -> Bool \ ef, l: List[a]): Bool \ ef = List.forAll(f, l) redef memberOf(x: a, l: List[a]): BoolwithEq[a] = List.memberOf(x, l) }instanceTraversable[List] {pubdeftraverse(f: a -> m[b] \ ef, t: List[a]): m[List[b]] \ efwithApplicative[m] = List.traverse(f, t) redef sequence(t: List[m[a]]): m[List[a]] withApplicative[m] = List.sequence(t) }instanceFilterable[List] {pubdeffilterMap(f: a -> Option[b] \ ef, x: List[a]): List[b] \ ef = List.filterMap(f, x) redef filter(f: a -> Bool \ ef, x: List[a]): List[a] \ ef = List.filter(f, x) }instanceWitherable[List]instanceSemiGroup[List[a]] {pubdefcombine(x: List[a], y: List[a]): List[a] = x:::y }instanceMonoid[List[a]] {pubdefempty(): List[a] = Nil }instanceCollectable[List[a]] {typeElm = apubdefcollect(iter: Iterator[a, ef, r]): List[a] \ { r, ef } = Iterator.toList(iter) }instanceIterable[List[a]] {typeElm = apubdefiterator(rc: Region[r], l: List[a]): Iterator[a, r, r] \ r = List.iterator(rc, l) }instanceForEach[List[a]] {typeElm = apubdefforEach(f: a -> Unit \ ef, t: List[a]): Unit \ ef = List.forEach(f, t) }////// Renders the list `l` to a String.///pubdeftoString(l: List[a]): StringwithToString[a] = regionrc {List.iterator(rc, l) |> Iterator.map(ToString.toString) |> xs ->Iterator.append(xs, Iterator.singleton(rc, "Nil")) |> Iterator.join(" :: ") }////// Returns the empty list `Nil`.///@Terminatespubdefempty(): List[a] = Nil////// Returns true if and only if `l` is the empty list, i.e. `Nil`.///@TerminatespubdefisEmpty(l: List[a]): Bool = matchl {case Nil => truecase_ => false }////// Returns true if and only if `l` is a non-empty list.///@TerminatespubdefnonEmpty(l: List[a]): Bool = notisEmpty(l)////// Returns a new list with element `x` added to the front of list `l`.///@Terminatespubdefcons(x: a, l: List[a]): List[a] = Cons(x, l)////// Returns `Some(x)` if `x` is the first element of `l`.////// Returns `None` if `l` is empty.///@Terminatespubdefhead(l: List[a]): Option[a] = matchl {case Nil => Nonecasex :: _ => Some(x) }////// Returns `Some(x)` if `x` is the last element of `l`.////// Returns `None` if `l` is empty.///@Terminates@Tailrecpubdeflast(l: List[a]): Option[a] = matchl {case Nil => Nonecasex :: Nil => Some(x)case_ :: rs => last(rs) }////// Returns the element at position `i` in the list `l`.////// Throws `IndexOutOfBoundsException` if the index is out of bounds.///pubdefget(i: Int32, l: List[a]): a =matchnth(i, l) {case Some(x) => xcase None => indexOutOfBounds!("index ${i} is out of bounds for List of length ${length(l)}") }////// Optionally returns the element at position `i` in the list `l`.///@Terminatespubdefnth(i: Int32, l: List[a]): Option[a] =if (i<0) Noneelse { @Tailrecdefloop(ll, j) = matchll {case Nil => Nonecasex :: xs => if (j==0) Some(x) elseloop(xs, j-1) };loop(l, i) }////// Returns the number of elements in `l`.///@Terminatespubdeflength(l: List[a]): Int32 = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccase_ :: xs => loop(xs, acc+1) };loop(l, 0)////// Returns the number of elements in `l`.///@Terminatespubdefsize(l: List[a]): Int32 = length(l)////// Returns `l2` appended to `l1`.////// The infix operator `:::` is an alias for `append` (`l1 ::: l2 = append(l1, l2)`).///@Terminatespubdefappend(l1: List[a], l2: List[a]): List[a] =foldRight((x, acc) -> x :: acc, l2, l1)////// Returns `l2` appended to `reverse(l1)`.////// More efficient than `append(reverse(l1), l2)` as it does not use reverse.///@TerminatesdefreverseAppend(l1: List[a], l2: List[a]): List[a] =foldLeft((acc, x) -> x :: acc, l2, l1)////// Returns `true` if and only if `l` contains the element `x`.///@Terminates@TailrecpubdefmemberOf(a: a, l: List[a]): BoolwithEq[a] = matchl {case Nil => falsecasex :: xs => if (a==x) trueelsememberOf(a, xs) }////// Optionally finds the smallest element of `l` according to the `Order` on `a`.////// Returns `None` if `l` is empty.///pubdefminimum(l: List[a]): Option[a] withOrder[a] =reduceLeft(Order.min, l)////// Optionally finds the smallest element of `l` according to the given comparator `cmp`.////// Returns `None` if `l` is empty.///pubdefminimumBy(cmp: (a, a) -> Comparison, l: List[a]): Option[a] =reduceLeft(Order.minBy(cmp), l)////// Optionally finds the largest element of `l` according to the `Order` on `a`.////// Returns `None` if `l` is empty.///pubdefmaximum(l: List[a]): Option[a] withOrder[a] =reduceLeft(Order.max, l)////// Optionally finds the largest element of `l` according to the given comparator `cmp`.////// Returns `None` if `l` is empty.///pubdefmaximumBy(cmp: (a, a) -> Comparison, l: List[a]): Option[a] =reduceLeft(Order.maxBy(cmp), l)////// Optionally returns the position of `x` in `l`.///@TerminatespubdefindexOf(a: a, l: List[a]): Option[Int32] withEq[a] = @Tailrecdefloop(ll, acc) = matchll {case Nil => Nonecasex :: xs => if (a==x) Some(acc) elseloop(xs, acc+1) };loop(l, 0)////// Returns the positions of all occurrences of `x` in `l`.///pubdefindicesOf(x: a, l: List[a]): Vector[Int32] withEq[a] = @Tailrecdefloop(ll, acc, indices) = matchll {case Nil => indicescasey :: ys => if (x==y) loop(ys, acc+1, acc :: indices) elseloop(ys, acc+1, indices) };loop(l, 0, Nil) |> List.reverse |> List.toVector////// Returns a range of all valid indices of the list `l`.///pubdefindices(l: List[a]): Range[Int32] = Range.Range(0, length(l))////// Alias for `findLeft`.///@Terminatespubdeffind(f: a -> Bool \ ef, l: List[a]): Option[a] \ ef = findLeft(f, l)////// Optionally returns the first element of `l` that satisfies the predicate `f` when searching from left to right.///@Terminates@TailrecpubdeffindLeft(f: a -> Bool \ ef, l: List[a]): Option[a] \ ef = matchl {case Nil => Nonecasex :: xs => if (f(x)) Some(x) elsefindLeft(f, xs) }////// Optionally returns the first element of `l` that satisfies the predicate `f` when searching from right to left.///pubdeffindRight(f: a -> Bool \ ef, l: List[a]): Option[a] \ ef =l |> reverse |> findLeft(f)////// Returns a list of all integers between `b` (inclusive) and `e` (exclusive).////// Returns `Nil` if `b >= e`.///pubdefrange(b: Int32, e: Int32): List[Int32] = @Tailrecdefloop(i, acc) =if (i<b)accelseloop(i-1, i :: acc);loop(e-1, Nil)////// Returns a list with the element `x` repeated `n` times.////// Returns `Nil` if `n < 0`.///pubdefrepeat(n: Int32, a: a): List[a] = @Tailrecdefloop(i, acc) =if (i>=n)accelseloop(i+1, a :: acc);loop(0, Nil)////// Alias for `scanLeft`.///@Terminatespubdefscan(f: (b, a) -> b \ ef, s: b, l: List[a]): List[b] \ ef = scanLeft(f, s, l)////// Accumulates the result of applying `f` to `l` going left to right.////// That is, the result is of the form: `s :: f(s, x1) :: f(f(s, x1), x2) ...`.///@TerminatespubdefscanLeft(f: (b, a) -> b \ ef, s: b, l: List[a]): List[b] \ ef = @Tailrecdefloop(ll, bacc, acc) = matchll {case Nil => acccasex :: xs =>lety = f(bacc, x);loop(xs, y, y :: acc) };reverse(loop(l, s, s :: Nil))////// Accumulates the result of applying `f` to `l` going right to left.////// That is, the result is of the form: `... f(xn-1, f(xn, s)) :: f(xn, s) :: s`.///@TerminatespubdefscanRight(f: (a, b) -> b \ ef, s: b, l: List[a]): List[b] \ ef = @Tailrecdefloop(ll, bacc, acc) = matchll {case Nil => acccasex :: xs =>lety = f(x, bacc);loop(xs, y, y :: acc) };loop(reverse(l), s, s :: Nil)////// Returns the result of applying `f` to every element in `l`.////// That is, the result is of the form: `f(x1) :: f(x2) :: ...`.///@Terminatespubdefmap(f: a -> b \ ef, l: List[a]): List[b] \ ef = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs => loop(xs, f(x) :: acc) };reverse(loop(l, Nil))////// Return the singleton list with element `x`.///@Terminatespubdefpoint(a: a): List[a] = a :: Nil////// Apply every function from `f` to every argument from `x` and return a list with all results./// For `f = f1, f2, ...` and `x = x1, x2, ...` the results appear in the order/// `f1(x1), f1(x2), ..., f2(x1), f2(x2), ...`.///pubdefap(f: List[a -> b \ ef], x: List[a]): List[b] \ ef =map(g -> map(g, x), f) |> flatten////// Lift a binary function to work on lists of its original arguments, returning a list/// of applying all combinations of arguments./// For argument lists `l1 = x1, x2, ...` and `l2 = y1, y2, ...` the results appear in the order/// `f(x1,y1), f(x1,y2), ..., f(x2,y1), f(x2,y2), ...`.///pubdefmap2(f: t1 -> t2 -> r \ ef, l1: List[t1], l2: List[t2]): List[r] \ ef = Applicative.map2(f, l1, l2)////// Lift a ternary function to work on lists of its original arguments, returning a list/// of applying all combinations of arguments./// For argument lists `l1 = x1, x2, ...`, `l2 = y1, y2, ...` and `l3 = z1, z2, ...` the results appear/// in the following order:////// ```/// f(x1,y1,z1), f(x1,y1,z2), ..., f(x1,y2,z1), f(x1,y2,z2), ...,/// f(x2,y1,z1), f(x2,y1,z2), ..., f(x2,y2,z1), f(x2,y2,z2), ...`/// .../// ```///pubdefmap3(f: t1 -> t2 -> t3 -> r \ ef, l1: List[t1], l2: List[t2], l3: List[t3]): List[r] \ ef = Applicative.map3(f, l1, l2, l3)////// Lift a 4-ary function to work on lists of its original arguments, returning a list/// of applying all combinations of arguments. The results appear in the order extending the pattern from `map3`.///pubdefmap4(f: t1 -> t2 -> t3 -> t4 -> r \ ef, l1: List[t1], l2: List[t2], l3: List[t3], l4: List[t4]): List[r] \ ef = Applicative.map4(f, l1, l2, l3, l4)////// Lift a 5-ary function to work on lists of its original arguments, returning a list/// of applying all combinations of arguments. The results appear in the order extending the pattern from `map3`.///pubdefmap5(f: t1 -> t2 -> t3 -> t4 -> t5 -> r \ ef, l1: List[t1], l2: List[t2], l3: List[t3], l4: List[t4], l5: List[t5]): List[r] \ ef = Applicative.map5(f, l1, l2, l3, l4, l5)////// Returns the result of applying `f` to every element in `l` along with that element's index.////// That is, the result is of the form: `f(0, x0) :: f(1, x1) :: ...`.///@TerminatespubdefmapWithIndex(f: (Int32, a) -> b \ ef, l: List[a]): List[b] \ ef = @Tailrecdefloop(ll, i, acc) = matchll {case Nil => acccasex :: xs =>lety = f(i, x);loop(xs, i+1, y :: acc) };reverse(loop(l, 0, Nil))////// Returns the result of applying `f` to every element in `l` and concatenating the results.///pubdefflatMap(f: a -> List[b] \ ef, l: List[a]): List[b] \ ef = regionrc {letml = MutList.empty(rc);defloop(ll) = matchll {case Nil => ()casex :: xs => MutList.pushAll(f(x), ml); loop(xs) };loop(l);MutList.toList(ml) }////// Returns the reverse of `l`.///@Terminatespubdefreverse(l: List[a]): List[a] = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs => loop(xs, x :: acc) };loop(l, Nil)////// Returns `l` with its elements rotated `n` positions to the left.////// That is, returns a new list where the first `n mod length(l)` elements in `l`/// are the last `n mod length(l)` elements of the new list.///pubdefrotateLeft(n: Int32, l: List[a]): List[a] =letlen = length(l);if (len==0)lelse {letrem1 = n`Int32.remainder`len;letrotate = if (rem1<0) rem1+lenelserem1;drop(rotate, l) :::take(rotate, l) }////// Returns `l` with its elements rotated `n` positions to the right.////// That is, returns a new list where the last `n mod length(l)` elements in `l`/// are the first `n mod length(l)` elements of the new list.///pubdefrotateRight(n: Int32, l: List[a]): List[a] = rotateLeft(-n, l)////// Returns `l` with the element at index `i` replaced by `x`.////// Returns `l` if `i < 0` or `i > length(l)-1`.///@Terminatespubdefupdate(i: Int32, a: a, l: List[a]): List[a] = @Tailrecdefloop(ll, j, acc) = match (j, ll) {case (_, Nil) => lcase (0, _ :: xs) => reverseAppend(acc, a :: xs)case (_, x :: xs) => loop(xs, j-1, x :: acc) };loop(l, i, Nil)////// Returns `l` with every occurrence of `src` replaced by `dst`.///@Terminatespubdefreplace(src: {src = a}, dst: {dst = a}, l: List[a]): List[a] withEq[a] =map(e -> if (e==src#src) dst#dst elsee, l)////// Returns `l2` with the `n` elements starting at index `i` replaced with the elements of `l1`.////// If any of the indices `i, i+1, i+2, ... , i+n-1` are out of range in `l2` then no patching is done at these indices./// If `l1` becomes depleted then no further patching is done./// If patching occurs at index `i+j` in `l2`, then the element at index `j` in `l1` is used.///pubdefpatch(i: Int32, n: Int32, l1: List[a], l2: List[a]): List[a] = @Tailrecdefloop(ll1, ll2, c, acc) = match (ll1, ll2) {case (x :: xs, y :: ys) => {if (c>=iandc<i+n)loop(xs, ys, c+1, x :: acc)elseloop(l1, ys, c+1, y :: acc) }case_ => reverseAppend(acc, ll2) };loop(drop(-i, l1), l2, 0, Nil)////// Returns all permutations of `l` in lexicographical order by element indices in `l`.////// That is, `l` is the first permutation and `reverse(l)` is the last permutation.///pubdefpermutations(l: List[a]): List[List[a]] = matchl {case Nil => Nil :: Nilcase_ => permutationHelper(0, l) }////// Helper function for `permutations`./// Returns all permutations of `l` starting with an element at or after index `i`.///defpermutationHelper(i: Int32, l: List[a]): List[List[a]] =if (i==length(l)) NilelseapplyHelper(at(i, l), permutations(removeIndex(i, l))) :::permutationHelper(i+1, l)////// Helper function for `permutations`.///defat(i: Int32, l: List[a]): a = match (i, l) {case (0, x :: _) => xcase (p, _ :: xs) => at(p-1, xs)case_ => unreachable!() }////// Helper function for `permutations`.///@TerminatesdefremoveIndex(i: Int32, l: List[a]): List[a] = match (i, l) {case (_, Nil) => lcase (0, _ :: xs) => xscase (p, x :: xs) => x :: removeIndex(p-1, xs) }////// Returns `l` without adjacent duplicates according to their `Eq` instance.////// The first occurrence in a chain of duplicates is kept.///@TerminatespubdefremoveAdjDups(l: List[a]): List[a] withEq[a] = removeAdjDupsWith(Eq.eq, l)////// Returns `l` without adjacent duplicates according to the function `f`./// Elements `x` and `y` are duplicates if and only if `f(x, y) = true`.////// The first occurrence in a chain of duplicates is kept.////// `f` must define an equivalence relation on the elements of the list.///@TerminatespubdefremoveAdjDupsWith(f: a -> a -> Bool \ ef, l: List[a]): List[a] \ ef = { @Tailrecdefloop(head, acc, ll) = matchll {case Nil => acccasex :: xs =>if (f(head, x)) {loop(head, acc, xs) } else {loop(x, x :: acc, xs) } };matchl {case Nil => Nilcasex :: xs => reverse(loop(x, x :: Nil, xs)) } }////// Returns all subsequences of `l` in lexicographical order by element indices in `l`.////// That is, `l` is the first subsequence and `Nil` is the last subsequence.///pubdefsubsequences(l: List[a]): List[List[a]] = matchl {case Nil => Nil :: Nilcasex :: xs =>letr = subsequences(xs);applyHelper(x, r) :::r }////// Helper function for `permutations` and `subsequences`./// Returns `l` with `x` added to the beginning of each element in `l`.///@TerminatesdefapplyHelper(a: a, l: List[List[a]]): List[List[a]] = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs => loop(xs, (a :: x) :: acc) };reverse(loop(l, Nil))////// Returns `l` with `x` inserted between every two adjacent elements.///pubdefintersperse(a: a, l: List[a]): List[a] = @Tailrecdefloop(ll, acc) = matchll {casex1 :: Nil => x1 :: acccasex1 :: xs => loop(xs, a :: x1 :: acc)case_ => unreachable!() };matchl {case Nil => Nilcase_ => reverse(loop(l, Nil)) }////// Returns the concatenation of the elements in `l2` with the elements of `l1` inserted between every two adjacent elements.////// That is, returns `y1 :: x1 ... xn :: y2 :: ... yn-1 :: x1 :: ... :: xn :: yn :: Nil`.///pubdefintercalate(l1: List[a], l2: List[List[a]]): List[a] = @Tailrecdefloop(ll, acc) = matchll {casex :: Nil => reverseAppend(x, acc)casex1 :: xs => loop(xs, reverseAppend(l1, reverseAppend(x1, acc)))case_ => unreachable!() };matchl2 {case Nil => Nilcase_ => reverse(loop(l2, Nil)) }////// Returns the transpose of `l`.////// Returns `l` if the dimensions of the elements of `l` are mismatched.///pubdeftranspose(l: List[List[a]]): List[List[a]] = matchl {case Nil => Nilcasex :: _ =>letlen = length(x);if (notuniformHelper(l, len) orlen==0) lelsetransposeHelper(l, len) }////// Helper function for `transpose`.///@Terminates@TailrecdefuniformHelper(l: List[List[a]], len: Int32): Bool = matchl {case Nil => truecasex :: xs => if (length(x) ==len) uniformHelper(xs, len) elsefalse }////// Helper function for `transpose`.///deftransposeHelper(l: List[List[a]], len: Int32): List[List[a]] = matchl {case Nil => repeat(len, Nil)casex :: xs => applyListHelper(x, transposeHelper(xs, len)) }////// Helper function for `transpose`.///defapplyListHelper(l1: List[a], l2: List[List[a]]): List[List[a]] = match (l1, l2) {case (Nil, Nil) => Nilcase (x :: xs, y :: ys) => (x :: y) :: applyListHelper(xs, ys)case_ => unreachable!() }////// Returns `true` if and only if `l1` is a prefix of `l2`.///@Terminates@TailrecpubdefisPrefixOf(l1: List[a], l2: List[a]): BoolwithEq[a] = match (l1, l2) {case (Nil, _) => truecase (_, Nil) => falsecase (x :: xs, y :: ys) => if (x==y) isPrefixOf(xs, ys) elsefalse }////// Returns `true` if and only if `l1` is an infix of `l2`.///@Terminates@TailrecpubdefisInfixOf(l1: List[a], l2: List[a]): BoolwithEq[a] = match (l1, l2) {case (Nil, _) => truecase (_, Nil) => falsecase (_, _ :: ys) => if (isPrefixOf(l1, l2)) trueelseisInfixOf(l1, ys) }////// Returns `true` if and only if `l1` is a suffix of `l2`.///@TerminatespubdefisSuffixOf(l1: List[a], l2: List[a]): BoolwithEq[a] = isPrefixOf(reverse(l1), reverse(l2))////// Returns the result of applying `combine` to all the elements in `l`, using `empty` as the initial value.///pubdeffold(l: List[a]): awithMonoid[a] = Foldable.fold(l)////// Applies `f` to a start value `s` and all elements in `l` going from left to right.////// That is, the result is of the form: `f(...f(f(s, x1), x2)..., xn)`.///@Terminates@TailrecpubdeffoldLeft(f: (b, a) -> b \ ef, s: b, l: List[a]): b \ ef = matchl {case Nil => scasex :: xs => foldLeft(f, f(s, x), xs) }////// Applies `f` to a start value `s` and all elements in `l` going from right to left.////// That is, the result is of the form: `f(x1, ...f(xn-1, f(xn, s))...)`.///@TerminatespubdeffoldRight(f: (a, b) -> b \ ef, s: b, l: List[a]): b \ ef = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs => loop(xs, f(x, acc)) };loop(reverse(l), s)////// Applies `f` to all elements in `l` going from left to right until a single value `v` is obtained. Returns `Some(v)`.////// That is, the result is of the form: `Some(f(...f(f(x1, x2), x3)..., xn))`////// Returns `None` if `l` is empty.///@TerminatespubdefreduceLeft(f: (a, a) -> a \ ef, l: List[a]): Option[a] \ ef = matchl {case Nil => Nonecasex :: xs => Some(foldLeft(f, x, xs)) }////// Applies `f` to all elements in `l` going from right to left until a single value `v` is obtained. Returns `Some(v)`.////// That is, the result is of the form: `Some(f(x1, ...f(xn-2, f(xn-1, xn))...))`////// Returns `None` if `l` is empty.///@TerminatespubdefreduceRight(f: (a, a) -> a \ ef, l: List[a]): Option[a] \ ef = @Tailrecdefloop(ll, acc) = matchll {case Nil => Some(acc)casex :: xs => loop(xs, f(x, acc)) };matchreverse(l) {case Nil => Nonecasex :: xs => loop(xs, x) }////// Returns the number of elements in `l` that satisfy the predicate `f`.///@Terminatespubdefcount(f: a -> Bool \ ef, l: List[a]): Int32 \ ef =foldLeft((acc, x) -> if (f(x)) acc+1elseacc, 0, l)////// Returns the concatenation of the elements in `l`.///@Terminatespubdefflatten(l: List[List[a]]): List[a] = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs => loop(xs, reverseAppend(x, acc)) };reverse(loop(l, Nil))////// Returns `true` if and only if at least one element in `l` satisfies the predicate `f`.////// Returns `false` if `l` is empty.///@Terminates@Tailrecpubdefexists(f: a -> Bool \ ef, l: List[a]): Bool \ ef = matchl {case Nil => falsecasex :: xs => if (f(x)) trueelseexists(f, xs) }////// Returns `true` if and only if all elements in `l` satisfy the predicate `f`.////// Returns `true` if `l` is empty.///@Terminates@TailrecpubdefforAll(f: a -> Bool \ ef, l: List[a]): Bool \ ef = matchl {case Nil => truecasex :: xs => if (f(x)) forAll(f, xs) elsefalse }////// Returns a list of every element in `l` that satisfies the predicate `f`.///@Terminatespubdeffilter(f: a -> Bool \ ef, l: List[a]): List[a] \ ef = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs => if (f(x)) loop(xs, x :: acc) elseloop(xs, acc) };reverse(loop(l, Nil))////// Returns the sublist of `l` without the last element./// Returns `None` if the list `l` is `Nil`.///pubdefinit(l: List[a]): Option[List[a]] = @Tailrecdefloop(ll, acc) = matchll {case_ :: Nil => acccasex :: xs => loop(xs, x :: acc)case Nil => unreachable!() };matchl {case Nil => Nonecase_ => Some(reverse(loop(l, Nil))) }////// Returns the sublist of `l` from index `start` (inclusive) to index `end` (exclusive).////// That is, an element at index `i` in `l` is part of the returned sublist if and only if `i >= start` and `i < end`./// Note: Indices that are out of bounds in `l` are not considered (i.e. slice(start, end, l) = slice(max(0, start), min(length(l), end), l)).///@Terminatespubdefslice(start: {start = Int32}, end: {end = Int32}, l: List[a]): List[a] = @Tailrecdefloop(ll, i, acc) = matchll {case Nil => acccasex :: xs =>if (i<start#start)loop(xs, i+1, acc)elseif (i>=end#end)accelseloop(xs, i+1, x :: acc) };if (start#start <end#end) reverse(loop(l, 0, Nil)) else Nil////// Returns a pair of lists `(l1, l2)`.////// `l1` contains all elements of `l` that satisfy the predicate `f`./// `l2` contains all elements of `l` that do not satisfy the predicate `f`.///@Terminatespubdefpartition(f: a -> Bool \ ef, l: List[a]): (List[a], List[a]) \ ef = @Tailrecdefloop(ll, acc1, acc2) = matchll {case Nil => (acc1, acc2)casex :: xs =>if (f(x))loop(xs, x :: acc1, acc2)elseloop(xs, acc1, x :: acc2) };let (l1, l2) = loop(l, Nil, Nil); (reverse(l1), reverse(l2))////// Returns a pair of lists `(l1, l2)`.////// `l1` is the longest prefix of `l` that satisfies the predicate `f`./// `l2` is the remainder of `l`.////// The function `f` must be pure.///@Terminatespubdefspan(f: a -> Bool, l: List[a]): (List[a], List[a]) = @Tailrecdefloop(ll, acc) = matchll {case Nil => (acc, Nil)casex :: xs =>if (f(x))loop(xs, x :: acc)else (acc, ll) };let (l1, l2) = loop(l, Nil); (reverse(l1), l2)////// Returns `l` without the first `n` elements.////// Returns `Nil` if `n > length(l)`./// Returns `l` if `n < 0`.///@Terminates@Tailrecpubdefdrop(n: Int32, l: List[a]): List[a] = matchl {case_ifn<=0 => lcase Nil => Nilcase_ :: xs => drop(n-1, xs) }////// Returns `l` without the longest prefix that satisfies the predicate `f`.///@Terminates@TailrecpubdefdropWhile(f: a -> Bool \ ef, l: List[a]): List[a] \ ef = matchl {case Nil => Nilcasex :: xs => if (f(x)) dropWhile(f, xs) elsel }////// Returns the first `n` elements of `l`.////// Returns `l` if `n > length(l)`./// Returns `Nil` if `n < 0`.///@Terminatespubdeftake(n: Int32, l: List[a]): List[a] = @Tailrecdefloop(ll, i, acc) =if (i<=0)accelsematchll {case Nil => acccasex :: xs => loop(xs, i-1, x :: acc) };reverse(loop(l, n, Nil))////// Returns the longest prefix of `l` that satisfies the predicate `f`.///@TerminatespubdeftakeWhile(f: a -> Bool \ ef, l: List[a]): List[a] \ ef = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs => if (f(x)) loop(xs, x :: acc) elseacc };reverse(loop(l, Nil))////// Split the list `xs` at the position `n` returning the left and right parts./// Position `n` is included in the right part.////// Example: `splitAt(2, 1::2::3::4::Nil)` returns `(1::2::Nil, 3::4::Nil)`////// Returns `(xs, Nil)` if `n > length(xs)`./// Returns `(Nil, xs)` if `n < 0`.///@TerminatespubdefsplitAt(n: Int32, xs: List[a]): (List[a], List[a]) = (List.take(n, xs), List.drop(n, xs))////// Partitions `l` into sublists such that for any two elements `x` and `y` in a sublist, `f(x, y)` is true.////// A sublist is created by iterating through the remaining elements of `l` from left to right and adding an/// element to the sublist if and only if doing so creates no conflicts with the elements already in the sublist.////// The function `f` must be pure and define an equivalence relation.///pubdefgroupWith(f: (a, a) -> Bool, l: List[a]): List[Nel[a]] = (Nil, l) ||> List.foldLeft(acc -> value -> {groupWithHelper(value, f, acc) } ) |> List.map(Nel.reverse)////// Partitions `l` into sublists such that for any two elements `x` and `y` in a sublist,/// if `f(x)` and `f(y)` are equal according to `Eq` on `b`.////// A sublist is created by iterating through the remaining elements of `l` from left to right and adding an/// element to the sublist if and only if doing so creates no conflicts with the elements already in the sublist.///pubdefgroupBy(f: a -> b, l: List[a]): List[Nel[a]] withEq[b] =groupWith(Eq.eq`on`f, l)////// Helper function for `groupWith`.////// Handles the 2 cases:////// 1. `value` can be added to a list. `value` is added as the first value to the `Nel`./// 2. `value` cannot be added to any list. Returns `List.reverse(currentNels) ::: (Nel(value, Nil) :: Nil)`.////// In either case the created `Nel`'s are reversed.///defgroupWithHelper(value: a, f: (a, a) -> Bool, currentNels: List[Nel[a]]): List[Nel[a]] =// Record seen elements in reverse order in `acc`. @Tailrecdefloop(cur, acc) = matchcur {case Nil => (Nel.singleton(value) :: acc) |> List.reversecasex :: xs =>if (f(value, Nel.head(x))) {letnewNel = Nel.cons(value, x);List.reverse(newNel :: acc) :::xs } else {loop(xs, x :: acc) } };loop(currentNels, Nil)////// Returns a list where the element at index `i` is `(a, b)` where/// `a` is the element at index `i` in `l1` and `b` is the element at index `i` in `l2`.////// If either `l1` or `l2` becomes depleted, then no further elements are added to the resulting list.///@Terminatespubdefzip(l1: List[a], l2: List[b]): List[(a, b)] = @Tailrecdefloop(ll1, ll2, acc) = match (ll1, ll2) {case (x :: xs, y :: ys) => loop(xs, ys, (x, y) :: acc)case_ => acc };reverse(loop(l1, l2, Nil))////// Returns a list where the element at index `i` is `f(a, b)` where/// `a` is the element at index `i` in `l1` and `b` is the element at index `i` in `l2`.////// If either `l1` or `l2` becomes depleted, then no further elements are added to the resulting list.///@TerminatespubdefzipWith(f: (a, b) -> c \ ef, l1: List[a], l2: List[b]): List[c] \ ef = @Tailrecdefloop(ll1, ll2, acc) = match (ll1, ll2) {case (x :: xs, y :: ys) =>letz = f(x, y);loop(xs, ys, z :: acc)case_ => acc };reverse(loop(l1, l2, Nil))////// Returns a list where each element `e` is mapped to `(i, e)` where `i`/// is the index of `e`.///@TerminatespubdefzipWithIndex(l: List[a]): List[(Int32, a)] = @Tailrecdefloop(ll, i, acc) = matchll {case Nil => acccase (x :: xs) => loop(xs, i+1, (i, x) :: acc) };reverse(loop(l, 0, Nil))////// Generalize `zipWith` to an applicative functor `f`.///pubdefzipWithA(f: (a, b) -> f[c] \ ef, xs: List[a], ys: List[b]): f[List[c]] \ efwithApplicative[f] =use Functor.{<$>};use Applicative.{<*>}; @Tailrecdefloop(l1, l2, k) = match (l1, l2) {case (x :: rs1, y :: rs2) => loop(rs1, rs2, ks -> k(((z, zs) -> z :: zs) <$> f(x, y) <*> ks))case (_, _) => k(Applicative.point(Nil)) };loop(xs, ys, x -> checked_ecast(x))////// Returns a pair of lists, the first containing all first components in `l`/// and the second containing all second components in `l`.///@Terminatespubdefunzip(l: List[(a, b)]): (List[a], List[b]) = @Tailrecdefloop(ll, acc1, acc2) = matchll {case Nil => (acc1, acc2)case (x1, x2) :: xs => loop(xs, x1 :: acc1, x2 :: acc2) };let (l1, l2) = loop(l, Nil, Nil); (reverse(l1), reverse(l2))////// Returns a list where the element at index `i` is `(a, b, c)` where/// `a` is the element at index `i` in `l1`, `b` is the element at index `i` in `l2`/// and `c` is the element at index `i` in `l3`.////// If any one of `l1`, `l2` or `l3` become depleted, then no further elements are added to the resulting list.///@Terminatespubdefzip3(l1: List[a], l2: List[b], l3: List[c]): List[(a, b, c)] =zipWith3((x, y, z) -> (x, y, z), l1, l2, l3)////// Returns a list where the element at index `i` is `f(a, b, c)` where/// `a` is the element at index `i` in `l1`, `b` is the element at index `i` in `l2`/// and `c` is the element at index `i` in `l3`.////// If any one of `l1`, `l2` or `l3` become depleted, then no further elements are added to the resulting list.///@TerminatespubdefzipWith3(f: (a, b, c) -> d \ ef, l1: List[a], l2: List[b], l3: List[c]): List[d] \ ef = @Tailrecdefloop(ll1, ll2, ll3, acc) = match (ll1, ll2, ll3) {case (x :: xs, y :: ys, z :: zs) =>letr = f(x, y, z);loop(xs, ys, zs, r :: acc)case_ => acc };reverse(loop(l1, l2, l3, Nil))////// Returns a triple of lists, the first containing all first components in `l`/// the second containing all second components in `l` and the third containing all/// third components in `l`.///@Terminatespubdefunzip3(l: List[(a, b, c)]): (List[a], List[b], List[c]) = @Tailrecdefloop(ll, acc1, acc2, acc3) = matchll {case Nil => (reverse(acc1), reverse(acc2), reverse(acc3))case (x, y, z) :: xs => loop(xs, x :: acc1, y :: acc2, z :: acc3) };loop(l, Nil, Nil, Nil)////// Alias for `foldLeft2`.///@Terminatespubdeffold2(f: (c, a, b) -> c \ ef, c: c, l1: List[a], l2: List[b]): c \ ef = foldLeft2(f, c, l1, l2)////// Accumulates the result of applying `f` pairwise to the elements of `l1` and `l2`/// starting with the initial value `c` and going from left to right.///@Terminates@TailrecpubdeffoldLeft2(f: (c, a, b) -> c \ ef, c: c, l1: List[a], l2: List[b]): c \ ef = match (l1, l2) {case (x :: xs, y :: ys) => foldLeft2(f, f(c, x, y), xs, ys)case_ => c }////// Accumulates the result of applying `f` pairwise to the elements of `l1` and `l2`/// starting with the initial value `c` and going from right to left.///@TerminatespubdeffoldRight2(f: (a, b, c) -> c \ ef, c: c, l1: List[a], l2: List[b]): c \ ef = @Tailrecdefloop(ll1, ll2, acc) = match (ll1, ll2) {case (x :: xs, y :: ys) => loop(xs, ys, f(x, y, acc))case_ => acc };loop(reverse(l1), reverse(l2), c)////// Returns the result of mapping each element and combining the results.///@TerminatespubdeffoldMap(f: a -> b \ ef, l: List[a]): b \ efwithMonoid[b] =foldLeft((acc, x) -> Monoid.combine(acc, f(x)), Monoid.empty(), l)////// Collects the results of applying the partial function `f` to every element in `l`.///@TerminatespubdeffilterMap(f: a -> Option[b] \ ef, l: List[a]): List[b] \ ef = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs =>matchf(x) {case None => loop(xs, acc)case Some(v) => loop(xs, v :: acc) } };reverse(loop(l, Nil))////// Returns the first non-None result of applying the partial function `f` to each element of `l`.////// Returns `None` if every element of `l` is `None`.///@Terminates@TailrecpubdeffindMap(f: a -> Option[b] \ ef, l: List[a]): Option[b] \ ef = matchl {case Nil => Nonecasex :: xs =>matchf(x) {case None => findMap(f, xs)case Some(v) => Some(v) } }////// Returns the concatenation of the string representation/// of each element in `l` with `sep` inserted between each element.///pubdefjoin(sep: String, l: List[a]): StringwithToString[a] =Foldable.join(sep, l)////// Returns the concatenation of the string representation/// of each element in `l` according to `f` with `sep` inserted between each element.///pubdefjoinWith(f: a -> String \ ef, sep: String, l: List[a]): String \ ef =Foldable.joinWith(f, sep, l)////// Returns the list `l` as a chain.///pubdeftoChain(l: List[a]): Chain[a] =List.foldLeft(Chain.snoc, Chain.empty(), l)////// Returns the list `l` as a set.///pubdeftoSet(l: List[a]): Set[a] withOrder[a] =foldRight(Set.insert, Set.empty(), l)////// Returns the association list `l` as a map.////// If `l` contains multiple mappings with the same key the last occurrence is kept.///pubdeftoMap(l: List[(a, b)]): Map[a, b] withOrder[a] =foldLeft((acc, x) -> Map.insert(fst(x), snd(x), acc), Map.empty(), l)////// Returns a map with mappings `k => v` where `(k, v) = f(x)` for some `x` in `l`.////// If multiple mappings with the same key are produced only the last occurrence is kept.///pubdeftoMapWith(f: a -> (k, v) \ ef, l: List[a]): Map[k, v] \ efwithOrder[k] =foldLeft( (acc, x) -> {let (key, val) = f(x);Map.insert(key, val, acc) },Map.empty(),l )////// Applies `f` to every element of `l`.///@Terminates@TailrecpubdefforEach(f: a -> Unit \ ef, l: List[a]): Unit \ ef = matchl {case Nil => ()casex :: xs => f(x); forEach(f, xs) }////// Applies `f` to every element of `l` along with that element's index.///@TerminatespubdefforEachWithIndex(f: (Int32, a) -> Unit \ ef, l: List[a]): Unit \ ef = @Tailrecdefloop(ll, i) = matchll {case Nil => ()casex :: xs => f(i, x); loop(xs, i+1) };loop(l, 0)////// Returns the list `l` as an array.///pubdeftoArray(rc: Region[r], l: List[a]): Array[a, r] \ r = matchhead(l) {case None => Array#{} @ rccase Some(_) =>leta = Array.empty(rc, length(l));forEach(match (i, b) -> Array.put(b, i, a), zipWithIndex(l));a }////// Returns the list `l` as a vector.///pubdeftoVector(l: List[a]): Vector[a] = regionrc {letarr = Array.empty(rc, length(l));forEachWithIndex((i, x) -> Array.put(x, i, arr), l);Array.toVector(arr) }////// Returns the list `l` as `Option[Nel[a]]`.////// If `l` is empty return `None`, otherwise return the Nel wrapped in `Some`.///pubdeftoNel(l: List[a]): Option[Nel[a]] = matchl {case Nil => Nonecasex :: xs => Some(Nel.Nel(x, xs)) }////// Returns the list `l` as `Option[Nec[a]]`.////// If `l` is empty return `None`, otherwise return the Nec wrapped in `Some`.///pubdeftoNec(l: List[a]): Option[Nec[a]] = matchl {case Nil => Nonecasex :: xs => Some(foldLeft(Nec.snoc, Nec.singleton(x), xs)) }////// Sort list `l` so that elements are ordered from low to high according to their `Order` instance.////// The sort is not stable, i.e., equal elements may appear in a different order than in the input `l`.////// The sort implementation is a Quicksort.///pubdefsort(l: List[a]): List[a] withOrder[a] = regionrc {toArray(rc, l) !> Array.sort |> Array.toList }////// Sort list `l` so that elements are ordered from low to high according to the `Order` instance/// for the values obtained by applying `f` to each element.////// The sort is not stable, i.e., equal elements may appear in a different order than in the input `l`.////// The sort implementation is a Quicksort.///pubdefsortBy(f: a -> b, l: List[a]): List[a] withOrder[b] = regionrc {toArray(rc, l) !> Array.sortBy(f) |> Array.toList }////// Sort list `l` so that elements are ordered from low to high according to the comparison function `cmp`.////// The sort is not stable, i.e., equal elements may appear in a different order than in the input `l`.////// The sort implementation is a Quicksort.///pubdefsortWith(cmp: (a, a) -> Comparison, l: List[a]): List[a] = regionrc {toArray(rc, l) !> Array.sortWith(cmp) |> Array.toList }////// Build a list by applying `f` to the seed value `st`.////// `f` should return `Some(a,st1)` to signal a new list element `a` and a new seed value `st1`.////// `f` should return `None` to signal the end of building the list.///pubdefunfold(f: s -> Option[(a, s)] \ ef, st: s): List[a] \ ef = @Tailrecdefloop(sst, acc) = matchf(sst) {case None => acccase Some((a, st1)) => loop(st1, a :: acc) };reverse(loop(st, Nil))////// Build a list by applying the function `next` to `()`. `next` is expected to encapsulate/// a stateful resource such as a file handle that can be iterated.////// `next` should return `Some(a)` to signal a new list element `a`.////// `next` should return `None` to signal the end of building the list.///pubdefunfoldWithIter(next: Unit -> Option[a] \ ef): List[a] \ ef = @Tailrecdefloop(acc) = matchnext() {case None => acccase Some(x) => loop(x :: acc) };reverse(loop(Nil))////// Build a list by applying the function `next` to `()`. `next` is expected to encapsulate/// a stateful resource such as a file handle that can be iterated.////// `next` should return `Ok(Some(a))` to signal a new list element `Ok(a)`.////// `next` should return `Ok(None)` to signal the end of building the list.////// `next` should return `Err(e)` to signal that an error occurred. The function returns `Err(e)`.///pubdefunfoldWithOkIter(next: Unit -> Result[e, Option[a]] \ ef): Result[e, List[a]] \ ef = @Tailrecdefloop(acc) = matchnext() {case Ok(None) => Ok(acc)case Ok(Some(x)) => loop(x :: acc)case Err(e) => Err(e) };matchloop(Nil) {case Ok(l) => Ok(reverse(l))case Err(err) => Err(err) }////// Build a list by applying `f` to the initial value `x`.////// `f` should return `Some(a1)` to signal a new list element `a1` (which also becomes the next input to `f`).////// `f` should return `None` to signal the end of building the list.///pubdefiterate(f: a -> Option[a] \ ef, x: a): List[a] \ ef = @Tailrecdefloop(st, acc) = matchf(st) {case None => acccase Some(a1) => loop(a1, a1 :: acc) };reverse(loop(x, Nil))////// Returns the list `l` with duplicates removed. The first occurrence of/// an element is kept and except for the removal of subsequent duplicates/// the order of `l` is preserved.////// `distinct` uses the Flix's builtin equality test. Use `distinctWith` if you/// need a custom equality test.///@Terminatespubdefdistinct(l: List[a]): List[a] withEq[a] = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs =>if (memberOf(x, acc))loop(xs, acc)elseloop(xs, x :: acc) };reverse(loop(l, Nil))////// Returns the list `l` with duplicates removed using the supplied function/// `f` for comparison. The first occurrence of an element is kept and except/// for the removal of subsequent duplicates the order of `l` is preserved.///@TerminatespubdefdistinctWith(f: (a, a) -> Bool, l: List[a]): List[a] = @Tailrecdefloop(ll, acc) = matchll {case Nil => acccasex :: xs =>if (exists(f(x), acc))loop(xs, acc)elseloop(xs, x :: acc) };reverse(loop(l, Nil))////// Returns the sum of all elements in the list `l`.///pubdefsum(l: List[Int32]): Int32 =Foldable.sum(l)////// Returns the sum of all elements in the list `l` according to the function `f`.///pubdefsumWith(f: a -> Int32 \ ef, l: List[a]): Int32 \ ef =Foldable.sumWith(f, l)////// Returns an iterator over `l`.///pubdefiterator(rc: Region[r], xs: List[a]): Iterator[a, r, r] \ r =letls = Ref.fresh(rc, xs);letnext = () -> {match (Ref.get(ls)) {case Nil => Nonecasex :: rs => Ref.put(rs, ls); Some(x) } };Iterator.unfoldWithIter(rc, next)////// Helper function for `sequence` and `traverse`.////// Builds an "applicative list" from a head of one applicative action and an/// applicative list of the tail.///defconsA(mx: f[a], ml: f[List[a]]): f[List[a]] withApplicative[f] =use Functor.{<$>};use Applicative.{<*>}; (((x, xs) -> x :: xs) <$> mx) <*> ml////// Returns the result of running all the actions in the list `l` going from left/// to right.///pubdefsequence(l: List[m[a]]): m[List[a]] withApplicative[m] = @Tailrecdefloop(ll, k) = matchll {case Nil => k(Applicative.point(Nil))casemx :: rs => loop(rs, ks -> k(consA(mx, ks))) };loop(l, identity)////// Returns the result of applying the applicative mapping function `f` to all the elements of the/// list `l` going from left to right.///pubdeftraverse(f: a -> m[b] \ ef, l: List[a]): m[List[b]] \ efwithApplicative[m] = @Tailrecdefloop(ll, k) = matchll {case Nil => k(Applicative.point(Nil))casex :: xs => { letans = f(x); loop(xs, ks -> k(consA(ans, ks))) } };loop(l, identity)////// Merges the two lists `l1` and `l2`. Assuming they are both sorted./// If two elements compare `EqualTo`, then the element of `l1` is first in the result.///@Terminatespubdefmerge(l1: List[a], l2: List[a]): List[a] withOrder[a] = @Tailrecdefloop(ll1, ll2, acc) = match (ll1, ll2) {case (x :: xs, y :: ys) => {letcmp = x<=>y;if (cmp== Comparison.LessThan orcmp== Comparison.EqualTo)loop(xs, ll2, x :: acc)elseloop(ll1, ys, y :: acc) }case (Nil, _) => reverse(reverseAppend(ll2, acc))case (_, Nil) => reverse(reverseAppend(ll1, acc)) };loop(l1, l2, Nil)////// Shuffles `l` using the Fisher–Yates shuffle.///pubdefshuffle(l: List[a]): List[a] \ Shuffle = regionrc {toArray(rc, l) !> Array.shuffle |> Array.toList }////// Returns the frequency for each element in list `l`///pubdeffrequency(l: List[t]): Map[t, Int32] withOrder[t] = @Tailrecdeffreq(ll, m) = matchll {case Nil => mcasex :: xs =>matchMap.get(x, m) {case None => freq(xs, Map.insert(x, 1, m))case Some(_) => freq(xs, Map.update(v -> Some(v+1), x, m)) } };freq(l, Map#{})}