/* * Copyright 2020 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 Nel {use Math.Shuffle////// The NonEmptyList type.///pubenumNel[a] {case Nel(a, List[a]) }instanceFormattable[Nel[a]] withFormattable[a] {typeAef = Formattable.Aef[a]pubdefformat(x: Nel[a]): RichString \ Formattable.Aef[a] =RichString.fromString("Nel#{") +RichString.joinWith(Formattable.format, RichString.fromString(", "), x) +RichString.fromString("}") }instanceToString[Nel[a]] withToString[a] {pubdeftoString(l: Nel[a]): String = Nel.toString(l) }instanceHash[Nel[a]] withHash[a] {pubdefhash(l: Nel[a]): Int32 = matchl {case Nel.Nel(x, xs) => Hash.hash(xs) `Hash.combine`Hash.hash(x) } }instanceEq[Nel[a]] withEq[a] {pubdefeq(l1: Nel[a], l2: Nel[a]): Bool = match (l1, l2) {case (Nel.Nel(x, xs), Nel.Nel(y, ys)) => x==yandxs==ys } }instanceOrder[Nel[a]] withOrder[a] {////// Compares `l1` and `l2` lexicographically.///pubdefcompare(l1: Nel[a], l2: Nel[a]): Comparison = match (l1, l2) {case (Nel.Nel(x, xs), Nel.Nel(y, ys)) =>letcmp = x<=>y;if (cmp== Comparison.EqualTo) xs<=>yselsecmp } }instanceFunctor[Nel] {pubdefmap(f: a -> b \ ef, l: Nel[a]): Nel[b] \ ef = Nel.map(f, l) }instanceApplicative[Nel] {pubdefpoint(x: a): Nel[a] = Nel.singleton(x)pubdefap(f: Nel[a -> b \ ef], x: Nel[a]): Nel[b] \ ef = Nel.ap(f, x) }instanceMonad[Nel] {pubdefflatMap(f: a -> Nel[b] \ ef, x: Nel[a]): Nel[b] \ ef = Nel.flatMap(f, x) }instanceMonadZip[Nel] {pubdefzipWith(f: (a, b) -> c \ ef, xs: Nel[a], ys: Nel[b]): Nel[c] \ ef = Nel.zipWith(f, xs, ys)pubdefzipWithA(f: (a, b) -> f[c] \ ef, xs: Nel[a], ys: Nel[b]): f[Nel[c]] \ efwithApplicative[f] = Nel.zipWithA(f, xs, ys) redef zip(xs: Nel[a], ys: Nel[b]): Nel[(a, b)] = Nel.zip(xs, ys) redef unzip(xs: Nel[(a, b)]): (Nel[a], Nel[b]) = Nel.unzip(xs) }instanceFoldable[Nel] {pubdeffoldLeft(f: (b, a) -> b \ ef, s: b, l: Nel[a]): b \ ef = Nel.foldLeft(f, s, l)pubdeffoldRight(f: (a, b) -> b \ ef, s: b, l: Nel[a]): b \ ef = Nel.foldRight(f, s, l) redef head(l: Nel[a]): Option[a] = Some(Nel.head(l)) redef isEmpty(_: Nel[a]): Bool = false redef memberOf(x: a, l: Nel[a]): BoolwithEq[a] = Nel.memberOf(x, l) redef forAll(f: a -> Bool \ ef, l: Nel[a]): Bool \ ef = Nel.forAll(f, l) redef exists(f: a -> Bool \ ef, l: Nel[a]): Bool \ ef = Nel.exists(f, l) }instanceUnorderedFoldable[Nel] {pubdeffoldMap(f: a -> b \ ef, l: Nel[a]): b \ efwithCommutativeMonoid[b] = Nel.foldMap(f, l) redef isEmpty(_: Nel[a]): Bool = false redef exists(f: a -> Bool \ ef, l: Nel[a]): Bool \ ef = Nel.exists(f, l) redef forAll(f: a -> Bool \ ef, l: Nel[a]): Bool \ ef = Nel.forAll(f, l) redef memberOf(x: a, l: Nel[a]): BoolwithEq[a] = Nel.memberOf(x, l) }instanceTraversable[Nel] {pubdeftraverse(f: a -> m[b] \ ef, t: Nel[a]): m[Nel[b]] \ efwithApplicative[m] = Nel.traverse(f, t) redef sequence(t: Nel[m[a]]): m[Nel[a]] withApplicative[m] = Nel.sequence(t) }instanceReducible[Nel] {pubdefreduceLeftTo(f: (b, a) -> b \ ef1, g: a -> b \ ef2, l: Nel[a]): b \ { ef1, ef2 } = Nel.reduceLeftTo(f, g, l)pubdefreduceRightTo(f: (a, b) -> b \ ef1, g: a -> b \ ef2, l: Nel[a]): b \ { ef1, ef2 } = Nel.reduceRightTo(f, g, l) redef head(l: Nel[a]): a = Nel.head(l) redef last(l: Nel[a]): a = Nel.last(l) redef init(l: Nel[a]): List[a] = Nel.init(l) redef tail(l: Nel[a]): List[a] = Nel.tail(l) redef exists(f: a -> Bool \ ef, l: Nel[a]): Bool \ ef = Nel.exists(f, l) redef forAll(f: a -> Bool \ ef, l: Nel[a]): Bool \ ef = Nel.forAll(f, l) redef find(f: a -> Bool \ ef, l: Nel[a]): Option[a] \ ef = Nel.find(f, l) redef findLeft(f: a -> Bool \ ef, l: Nel[a]): Option[a] \ ef = Nel.findLeft(f, l) redef findRight(f: a -> Bool \ ef, l: Nel[a]): Option[a] \ ef = Nel.findRight(f, l) redef memberOf(a: a, l: Nel[a]): BoolwithEq[a] = Nel.memberOf(a, l) redef dropWhile(f: a -> Bool \ ef, l: Nel[a]): List[a] \ ef = Nel.dropWhile(f, l) redef takeWhile(f: a -> Bool \ ef, l: Nel[a]): List[a] \ ef = Nel.takeWhile(f, l) redef toArray(rc: Region[r], l: Nel[a]): Array[a, r] \ r = Nel.toArray(rc, l) redef toVector(l: Nel[a]): Vector[a] = Nel.toVector(l) redef toList(l: Nel[a]): List[a] = Nel.toList(l) }instanceSemiGroup[Nel[a]] {pubdefcombine(x: Nel[a], y: Nel[a]): Nel[a] = Nel.append(x, y) }instanceIterable[Nel[a]] {typeElm = apubdefiterator(rc: Region[r], l: Nel[a]): Iterator[a, r, r] \ r = Nel.iterator(rc, l) }instanceForEach[Nel[a]] {typeElm = apubdefforEach(f: a -> Unit \ ef, l: Nel[a]): Unit \ ef = Nel.forEach(f, l) }////// Returns a string representation of the given non-empty list `l`.///pubdeftoString(l: Nel[a]): StringwithToString[a] = {let Nel(x, xs) = l;"Nel(${x}, ${xs})" }////// Returns a new non-empty list containing the single element `x`.///pubdefsingleton(x: a): Nel[a] = Nel(x, Nil)////// Returns the non-empty list `l` prefixed with the new element `x`.///pubdefcons(x: a, l: Nel[a]): Nel[a] = matchl {case Nel(y, ys) => Nel(x, y :: ys) }////// Returns the first element of `l`.///pubdefhead(l: Nel[a]): a = matchl {case Nel(x, _) => x }////// Returns the last element of `l`.///pubdeflast(l: Nel[a]): a = matchl {case Nel(x, xs) => Option.getWithDefault(x, List.last(xs)) }////// Returns the element at position `i` in the non-empty list `l`.////// Throws `IndexOutOfBoundsException` if the index is out of bounds.///pubdefget(i: Int32, l: Nel[a]): a =matchnth(i, l) {case Some(x) => xcase None => indexOutOfBounds!("index ${i} is out of bounds for Nel of length ${length(l)}") }////// Optionally returns the element at position `i` in the non-empty list `l`.///pubdefnth(i: Int32, l: Nel[a]): Option[a] = matchl {case Nel(x, xs) => if (i==0) Some(x) elseList.nth(i-1, xs) }////// Returns all elements in `l` without the last element.///pubdefinit(l: Nel[a]): List[a] = matchl {case Nel(_, Nil) => Nilcase Nel(x, xs) => matchList.reverse(xs) {case Nil => x :: Nilcase_ :: ys => x :: List.reverse(ys) } }////// Returns all elements in `l` without the first element.///pubdeftail(l: Nel[a]): List[a] = matchl {case Nel(_, xs) => xs }////// Returns the number of elements in `l`.///pubdeflength(l: Nel[a]): Int32 = matchl {case Nel(_, xs) => 1+List.length(xs) }////// Returns the number of elements in `l`.///pubdefsize(l: Nel[a]): Int32 = length(l)////// Returns `l2` appended to `l1`.///pubdefappend(l1: Nel[a], l2: Nel[a]): Nel[a] = match (l1, l2) {case (Nel(x, xs), Nel(y, ys)) => Nel(x, xs::: (y :: ys)) }////// Returns `true` if and only if `l` contains the element `a`.///pubdefmemberOf(a: a, l: Nel[a]): BoolwithEq[a] = matchl {case Nel(x, xs) => if (x==a) trueelseList.memberOf(a, xs) }////// Finds the smallest element of `l` according to the `Order` on `a`.///pubdefminimum(l: Nel[a]): awithOrder[a] =reduceLeft(Order.min, l)////// Finds the smallest element of `l` according to the given comparator `cmp`.///pubdefminimumBy(cmp: (a, a) -> Comparison, l: Nel[a]): a =reduceLeft(Order.minBy(cmp), l)////// Finds the largest element of `l` according to the `Order` on `a`.///pubdefmaximum(l: Nel[a]): awithOrder[a] =reduceLeft(Order.max, l)////// Finds the largest element of `l` according to the given comparator `cmp`.///pubdefmaximumBy(cmp: (a, a) -> Comparison, l: Nel[a]): a =reduceLeft(Order.maxBy(cmp), l)////// Returns a range of all valid indices of the non-empty list `l`.///pubdefindices(l: Nel[a]): Range[Int32] = Range.Range(0, length(l))////// Alias for `findLeft`.///pubdeffind(f: a -> Bool \ ef, l: Nel[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.///pubdeffindLeft(f: a -> Bool \ ef, l: Nel[a]): Option[a] \ ef = matchl {case Nel(x, xs) => if (f(x)) Some(x) elseList.findLeft(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: Nel[a]): Option[a] \ ef = matchl {case Nel(x, xs) => matchList.findRight(f, xs) {case None => if (f(x)) Some(x) else Nonecase Some(y) => Some(y) } }////// Returns the result of applying `f` to every element in `l`.////// That is, the result is of the form: `f(x1) :: f(x2) :: ...`.///pubdefmap(f: a -> b \ ef, l: Nel[a]): Nel[b] \ ef = matchl {case Nel(x, xs) => Nel(f(x), List.map(f, xs)) }////// 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) :: ...`.///pubdefmapWithIndex(f: (Int32, a) -> b \ ef, l: Nel[a]): Nel[b] \ ef =let Nel(x, xs) = l;matchList.mapWithIndex(f, x :: xs) {casey :: ys => Nel(y, ys)case_ => unreachable!() }////// Apply every function from `f` to every argument from `l` and return a non-empty 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: Nel[a -> b \ ef], l: Nel[a]): Nel[b] \ ef =// Note - loop has been worker-wrapper transformed to represent the list of// functions as head (f1) and tail (fs) so we never have an empty list to deal with.defloop(f1, fs, k) = matchfs {case Nil => k(map(f1, l))casef2 :: rs =>letks1 = map(f1, l);loop(f2, rs, ks2 -> k(append(ks1, ks2))) };matchf {case Nel(f1, Nil) => map(f1, l)case Nel(f1, rs) => loop(f1, rs, identity) }////// Returns the result of applying `f` to every element in `l` and concatenating the results.///pubdefflatMap(f: a -> Nel[b] \ ef, l: Nel[a]): Nel[b] \ ef = matchl {case Nel(x, xs) => matchf(x) {case Nel(y, ys) => Nel(y, ys:::List.flatMap(z -> toList(f(z)), xs)) } }////// Returns the reverse of `l`.///pubdefreverse(l: Nel[a]): Nel[a] = matchl {case Nel(x, xs) => matchList.reverse(x :: xs) {casey :: ys => Nel(y, ys)case_ => unreachable!() } }////// Returns `l` with every occurrence of `src` replaced by `dst`.///pubdefreplace(src: {src = a}, dst: {dst = a}, l: Nel[a]): Nel[a] withEq[a] =map(e -> if (e==src#src) dst#dst elsee, l)////// 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: Nel[a]): Nel[List[a]] = matchl {case Nel(x, xs) => matchList.permutations(x :: xs) {casey :: ys => Nel(y, ys)case Nil => unreachable!() } }////// 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: Nel[a]): Nel[List[a]] = matchl {case Nel(x, xs) => matchList.subsequences(x :: xs) {casey :: ys => Nel(y, ys)case Nil => unreachable!() } }////// Returns `l` with `a` inserted between every two adjacent elements.///pubdefintersperse(a: a, l: Nel[a]): Nel[a] = matchl {case Nel(x, Nil) => Nel(x, Nil)case Nel(x, xs) => Nel(x, a :: List.intersperse(a, xs)) }////// Returns the result of applying `combine` to all the elements in `l`, using `empty` as the initial value.///pubdeffold(l: Nel[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)`.///pubdeffoldLeft(f: (b, a) -> b \ ef, s: b, l: Nel[a]): b \ ef = matchl {case Nel(x, xs) => List.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))...)`.///pubdeffoldRight(f: (a, b) -> b \ ef, s: b, l: Nel[a]): b \ ef = matchl {case Nel(x, xs) => f(x, List.foldRight(f, s, xs)) }////// Returns the result of mapping each element and combining the results.///pubdeffoldMap(f: a -> b \ ef, l: Nel[a]): b \ efwithMonoid[b] =foldLeft((acc, x) -> Monoid.combine(acc, f(x)), Monoid.empty(), l)////// Left-associative reduction of a structure./// Applies `g` to the initial element of `l` and combines it/// with the remainder of `l` using `f` going from left to right.///pubdefreduceLeftTo(f: (b, a) -> b \ ef1, g: a -> b \ ef2, l: Nel[a]): b \ { ef1, ef2 } = matchl {case Nel(x, xs) => List.foldLeft(f, g(x), xs) }////// Right-associative reduction of a structure./// Applies `g` to the initial element of `l` and combines it/// with the remainder of `l` using `f` going from right to left.///pubdefreduceRightTo(f: (a, b) -> b \ ef1, g: a -> b \ ef2, l: Nel[a]): b \ { ef1, ef2 } =defloop(ll, k) = matchll {casex :: Nil => k(g(x))casex :: xs => loop(xs, ks -> k(f(x, ks)))case_ => unreachable!() };let Nel(x, xs) = l;loop(x :: xs, z -> checked_ecast(z))////// Applies `combine` to all elements in `l` until a single value is obtained.///pubdefreduce(l: Nel[a]): awithSemiGroup[a] = matchl {case Nel(x, xs) => Foldable.foldLeft(SemiGroup.combine, x, xs) }////// Applies `f` to all elements in `l` going from left to right until a single value `v` is obtained.////// That is, the result is of the form: `f(...f(f(x1, x2), x3)..., xn)`///pubdefreduceLeft(f: (a, a) -> a \ ef, l: Nel[a]): a \ ef = matchl {case Nel(x, xs) => List.foldLeft(f, x, xs) }////// Applies `f` to all elements in `l` going from right to left until a single value `v` is obtained.////// That is, the result is of the form: `f(x1, ...f(xn-2, f(xn-1, xn))...)`///pubdefreduceRight(f: (a, a) -> a \ ef, l: Nel[a]): a \ ef = matchl {case Nel(x, xs) => matchList.reduceRight(f, x :: xs) {case None => unreachable!()case Some(v) => v } }////// Returns the number of elements in `l` that satisfy the predicate `f`.///pubdefcount(f: a -> Bool \ ef, l: Nel[a]): Int32 \ ef = matchl {case Nel(x, xs) => (if (f(x)) 1else0) +List.count(f, xs) }////// Returns the sum of all elements in the list `l`.///pubdefsum(l: Nel[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: Nel[a]): Int32 \ ef =Foldable.sumWith(f, l)////// Returns the concatenation of the elements in `l`.///pubdefflatten(l: Nel[Nel[a]]): Nel[a] = matchl {case Nel(Nel(y, ys), xs) => Nel(y, ys:::List.flatMap(toList, xs)) }////// Returns `true` if and only if at least one element in `l` satisfies the predicate `f`.///pubdefexists(f: a -> Bool \ ef, l: Nel[a]): Bool \ ef = matchl {case Nel(x, xs) => if (f(x)) trueelseList.exists(f, xs) }////// Returns `true` if and only if all elements in `l` satisfy the predicate `f`.///pubdefforAll(f: a -> Bool \ ef, l: Nel[a]): Bool \ ef = matchl {case Nel(x, xs) => if (f(x)) List.forAll(f, xs) elsefalse }////// Returns a list of every element in `l` that satisfies the predicate `f`.///pubdeffilter(f: a -> Bool, l: Nel[a]): List[a] = matchl {case Nel(x, xs) =>if (f(x))x :: List.filter(f, xs)elseList.filter(f, xs) }////// Returns a non-empty 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.///pubdefzip(l1: Nel[a], l2: Nel[b]): Nel[(a, b)] = match (l1, l2) {case (Nel(x, xs), Nel(y, ys)) => Nel((x, y), List.zip(xs, ys)) }////// Returns a non-empty 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.///pubdefzipWith(f: (a, b) -> c \ ef, l1: Nel[a], l2: Nel[b]): Nel[c] \ ef = match (l1, l2) {case (Nel(x, xs), Nel(y, ys)) => Nel(f(x, y), List.zipWith(f, xs, ys)) }////// Returns a pair of non-empty lists, the first containing all first components in `l`/// and the second containing all second components in `l`.///pubdefunzip(l: Nel[(a, b)]): (Nel[a], Nel[b]) =let Nel((a, b), xs) = l;let (l1, l2) = List.unzip(xs); (Nel(a, l1), Nel(b, l2))////// Returns a new non-empty list where each element `e` is mapped to `(i, e)`/// where `i` is the index of `e`.///pubdefzipWithIndex(l: Nel[a]): Nel[(Int32, a)] =defloop(ll, k, i) = matchll {case (x :: xs) => loop(xs, ks -> (k((i, x) :: ks)), i+1)case Nil => k(Nil) };matchl {case Nel(x, xs) => Nel((0, x), loop(xs, identity, 1)) }////// Generalize `zipWith` to an applicative functor `f`.///pubdefzipWithA(f: (a, b) -> m[c] \ ef, xs: Nel[a], ys: Nel[b]): m[Nel[c]] \ efwithApplicative[m] =use Functor.{<$>};use Applicative.{<*>};match (xs, ys) {case (Nel(x, l1), Nel(y, l2)) => ((c, cs) -> Nel(c, cs)) <$> f(x, y) <*> List.zipWithA(f, l1, l2) }////// Returns `l` as a normal list.///pubdeftoList(l: Nel[a]): List[a] = matchl {case Nel(x, xs) => x :: xs }////// Returns `l` as an array.///pubdeftoArray(rc: Region[r], l: Nel[a]): Array[a, r] \ r =l |> toList |> List.toArray(rc)////// Returns `l` as a vector.///pubdeftoVector(l: Nel[a]): Vector[a] = regionrc {letarr = Array.empty(rc, length(l));forEachWithIndex((i, x) -> Array.put(x, i, arr), l);Array.toVector(arr) }////// Applies `f` to every element of `l`.///pubdefforEach(f: a -> Unit \ ef, l: Nel[a]): Unit \ ef = matchl {case Nel(x, xs) => f(x); List.forEach(f, xs) }////// Applies `f` to every element of `l` along with that element's index.///pubdefforEachWithIndex(f: (Int32, a) -> Unit \ ef, l: Nel[a]): Unit \ ef = matchl {case Nel(x, xs) => List.forEachWithIndex(f, x :: xs) }////// Sort the non-empty 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: Nel[a]): Nel[a] withOrder[a] = regionrc {letlist = toArray(rc, l) !> Array.sort |> Array.toList;matchlist {casex :: xs => Nel(x, xs)case_ => unreachable!() } }////// Sort the non-empty 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: Nel[a]): Nel[a] withOrder[b] = regionrc {letlist = toArray(rc, l) !> Array.sortBy(f) |> Array.toList;matchlist {casex :: xs => Nel(x, xs)case_ => unreachable!() } }////// Sort the non-empty 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: Nel[a]): Nel[a] = regionrc {letlist = toArray(rc, l) !> Array.sortWith(cmp) |> Array.toList;matchlist {casex :: xs => Nel(x, xs)case_ => unreachable!() } }////// Returns an iterator over `l`.///pubdefiterator(rc: Region[r], l: Nel[a]): Iterator[a, r, r] \ r =let Nel(x, xs) = l;List.iterator(rc, x :: xs)////// Returns the result of applying the applicative mapping function `f` to all the elements of the/// non-empty list `l`.///pubdefsequence(l: Nel[m[a]]): m[Nel[a]] withApplicative[m] =matchl {case Nel(x, xs) => (((y, ys) -> Nel(y, ys)) `Functor.map`x) `Applicative.ap`Traversable.sequence(xs) }////// Returns the result of running all the actions in the non-empty list `l`.///pubdeftraverse(f: a -> m[b] \ ef, l: Nel[a]): m[Nel[b]] \ efwithApplicative[m] =matchl {case Nel(x, xs) => (((y, ys) -> Nel(y, ys)) `Functor.map`f(x)) `Applicative.ap`Traversable.traverse(f, xs) }////// Returns a map with elements of `l` as keys and `f` applied as values.////// If `l` contains multiple mappings with the same key, `toMapWith` does not/// make any guarantees about which mapping will be in the resulting map.///pubdeftoMapWith(f: a -> b, l: Nel[a]): Map[a, b] withOrder[a] =Nel.foldRight((x, acc) -> Map.insert(x, f(x), acc), Map.empty(), l)////// Returns the concatenation of the string representation/// of each element in `l` with `sep` inserted between each element.///pubdefjoin(sep: String, l: Nel[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: Nel[a]): String \ ef =Foldable.joinWith(f, sep, l)////// Returns `l` without the longest prefix that satisfies the predicate `f`.///pubdefdropWhile(f: a -> Bool \ ef, l: Nel[a]): List[a] \ ef =let Nel(x, xs) = l;List.dropWhile(f, x :: xs)////// Returns the longest prefix of `l` that satisfies the predicate `f`.///pubdeftakeWhile(f: a -> Bool \ ef, l: Nel[a]): List[a] \ ef =let Nel(x, xs) = l;List.takeWhile(f, x :: xs)////// Optionally returns the Nel `l` shuffled using the Fisher–Yates shuffle.///pubdefshuffle(l: Nel[a]): Option[Nel[a]] \ Shuffle = regionrc {toArray(rc, l) !> Array.shuffle |> Array.toNel }////// Build a non-empty list by applying `f` to the seed value `st`.////// `f` should return `Some(a, st1)` to signal a new element `a` and a new seed value `st1`.////// `f` should return `None` to signal the end of building the list.////// The first element is produced from the initial seed, so the result is always non-empty/// only if `f(st)` returns `Some`. Returns `None` if `f(st)` immediately returns `None`.///pubdefunfold(f: s -> Option[(a, s)] \ ef, st: s): Option[Nel[a]] \ ef =matchf(st) {case None => Nonecase Some((a, st1)) => @Tailrecdefloop(sst, acc) = matchf(sst) {case None => acccase Some((b, st2)) => loop(st2, b :: acc) }; Some(Nel(a, List.reverse(loop(st1, Nil)))) }////// Build a non-empty 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 element `a`.////// `next` should return `None` to signal the end of building the list.////// Returns `None` if `next` immediately returns `None`.///pubdefunfoldWithIter(next: Unit -> Option[a] \ ef): Option[Nel[a]] \ ef =matchnext() {case None => Nonecase Some(a) => @Tailrecdefloop(acc) = matchnext() {case None => acccase Some(x) => loop(x :: acc) }; Some(Nel(a, List.reverse(loop(Nil)))) }////// Build a non-empty list by applying `f` to the initial value `x`.////// `f` should return `Some(a1)` to signal a new element `a1` (which also becomes the next input to `f`).////// `f` should return `None` to signal the end of building the list.////// Returns `None` if `f(x)` immediately returns `None`.///pubdefiterate(f: a -> Option[a] \ ef, x: a): Option[Nel[a]] \ ef =matchf(x) {case None => Nonecase Some(a1) => @Tailrecdefloop(st, acc) = matchf(st) {case None => acccase Some(a2) => loop(a2, a2 :: acc) }; Some(Nel(a1, List.reverse(loop(a1, Nil)))) }}