Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 1x 1x 1x 1x 41x 1x 8058x 8058x 8058x 8058x 8058x 8058x 8058x 8058x 8058x 8008x 8008x 8008x 8008x 8008x 8008x 8008x 8008x 8058x 8058x 1x 1x 8419x 8277x 8277x 8277x 8277x 8277x 8277x 8277x 8277x 8050x 8050x 8050x 8050x 8050x 8050x 8050x 8050x 8050x 8050x 8050x 8050x 8050x 8050x 8050x 8277x 8277x 8277x 1x 142x 142x 142x 142x 1x 1x 1x 1x 142x 1x | import {getValue, leaf, match, tree, type Tree, treeCata} from '#tree'
import * as TreeF from '#treeF'
import {Array, Effect, Function, pipe, Tuple} from 'effect'
/**
* Unzip a tree of `[A, B]` into a pair of congruent trees of types `A` and `B`.
*
* ```ts
* const zippedTree: Tree<[string, number]> = tree(
* ['a', 1],
* [leaf(['b', 2])],
* )
*
* const [left, right] = unzip(zippedTree)
* // left = branch('a', [leaf('b')])
* // right = branch( 1 , [leaf( 2 )])
* ```
* @category ops
* @function
*/
export const unzip: <A, B>(t: Tree<[A, B]>) => [Tree<A>, Tree<B>] = tree =>
pipe(tree, treeCata(unzipFold))
/**
* Unzip a single level in a tree of `[A, B]` into a pair of trees of types `A`
* and `B`.
* @category fold
* @function
*/
export const unzipFold = <A, B>(
t: TreeF.TreeF<[A, B], [Tree<A>, Tree<B>]>,
): [Tree<A>, Tree<B>] =>
pipe(
t,
TreeF.match({
onLeaf: Tuple.mapBoth({
onFirst: leaf,
onSecond: leaf,
}),
onBranch: ([a, b], nodes) =>
pipe(
nodes,
Array.unzip,
Tuple.mapBoth({
onFirst: tree.flipped(a),
onSecond: tree.flipped(b),
}),
),
}),
)
/**
* Just like {@link zipWith} except the given function returns its result in an
* `Effect`.
* @category ops
* @function
*/
export const zipWithEffect =
<A, B, C>(f: (self: A, that: B) => C) =>
(self: Tree<A>, that: Tree<B>): Effect.Effect<Tree<C>> => {
const zip = Function.tupled(zipWithEffect(f)),
value = f(getValue(self), getValue(that)),
onLeaf = () => pipe(value, leaf, Effect.succeed)
return pipe(
self,
match({
onLeaf,
onBranch: (_, selfForest) =>
pipe(
that,
match({
onLeaf,
onBranch: (_, thatForest) =>
Effect.suspend(() =>
pipe(
selfForest,
Array.zip(thatForest),
Effect.forEach(zip),
Effect.map(tree.flipped(value)),
),
),
}),
),
}),
)
}
/**
* Zip a pair of trees cropping to the smallest degree and depth, and apply the
* given function.
*
* Returns the smallest matching tree of pairs, one taken from each tree at the
* same position, and run the given function on this pair, returning a tree of
* its results.
* @category ops
* @function
*/
export const zipWith = <A, B, C>(
self: Tree<A>,
that: Tree<B>,
f: (a: A, b: B) => C,
): Tree<C> => Effect.runSync(zipWithEffect(f)(self, that))
/**
* Zip a pair of trees of types `A` and `B` into a single tree of `[A, B]`.
*
* If their shapes do not match, the result will include only the intersection.
* Any nodes not on the shape of the intersection of the two trees will be
* discarded.
*
* See {@link zipThese} for a zip that does not crop and is therefore pleasantly
* associative.
*
* ```ts
* // Zip two trees of identical shape
* const left: Tree<string> = branch('a', [branch('b', [of('c')])]),
right: Tree<number> = branch( 1 , [branch( 2 , [of( 3 )])])
* const zippedTree: Tree<[string, number]> = zip(left, right)
* // zippedTree = branch(
* // ['a', 1],
* // [branch(['b', 2], [of(['c', 3])])],
* // )
*
* // Zipping trees of different shapes crops to intersection
* const left: Tree<string> = branch('a', [branch('b', [of('c')])]),
right: Tree<number> = leaf( 1 )
* const zippedTree: Tree<[string, number]> = pipe(right, zip(left))
* // zippedTree = leaf(['a', 1])
* ```
* @category ops
* @function
*/
export const zip: {
<A, B>(self: Tree<A>, that: Tree<B>): Tree<[A, B]>
<B>(that: Tree<B>): <A>(self: Tree<A>) => Tree<[A, B]>
} = Function.dual(
2,
<A, B>(self: Tree<A>, that: Tree<B>): Tree<[A, B]> =>
zipWith(self, that, (a, b) => [a, b]),
)
|