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 | 1x 1x 1x 1x 1x 3x 1894x 1894x 1894x 1894x 1894x 1894x 1894x 1894x 1x 1x 3986x 2092x 2092x 2092x 2092x 2092x 1670x 1670x 1670x 1670x 1387x 1387x 587x 800x 1387x 1670x 1670x 1670x 2092x 422x 422x 422x 422x 422x 141x 141x 40x 40x 141x 10x 141x 7x 7x 84x 84x 84x 84x 84x 84x 84x 84x 141x 422x 422x 2092x 2092x 2092x | import {Array, Function, K, pipe, type Order} from '#util'
import {Effect, identity} from 'effect'
import {match} from '../tree/index.js'
import type {Tree} from '../tree/types.js'
/**
* Build an order for {@link Tree} from and order of its underlying type.
* @example
* import {getOrder, from, of} from 'effect-tree'
* import {Number, Array, pipe} from 'effect'
*
* const t1 = of(1)
* const t2 = of(2)
* const t3 = from(1, of(2))
* const t4 = from(1, of(1), of(2))
* const t5 = from(1, of(2), of(1))
* const t6 = from(2, of(1))
* const t7 = from(2, of(1), of(2))
*
* const sort = pipe(Number.Order, getOrder, Array.sortBy)
*
* expect(
* sort(
* [t7, t6, t5, t4, t3, t2, t1]
* )
* ).toEqual(
* [t1, t2, t3, t4, t5, t6, t7]
* )
* @category instances
* @function
*/
export const getOrder =
<A>(orderA: Order.Order<A>): Order.Order<Tree<A>> =>
(self: Tree<A>, that: Tree<A>) =>
pipe(
getOrderEffect(orderA)(self, that),
Effect.match({
onSuccess: K<0>(0),
onFailure: identity<-1 | 1>,
}),
Effect.runSync,
)
// We use effect _success_ to encode equality and effect _failure_ of `-1 | 1`
// to encode greater than/less than.
const getOrderEffect =
<A>(orderA: Order.Order<A>) =>
(self: Tree<A>, that: Tree<A>): Effect.Effect<void, -1 | 1> => {
const order = Function.tupled(getOrderEffect(orderA))
return pipe(
self,
match({
onLeaf: selfValue =>
pipe(
that,
match({
onLeaf: thatValue => {
const valueOrder = orderA(selfValue, thatValue)
return valueOrder === 0
? Effect.succeed(void {})
: Effect.fail(valueOrder)
},
onBranch: K(Effect.fail(-1)),
}),
),
onBranch: (selfValue, selfForest) =>
pipe(
that,
match({
onLeaf: K(Effect.fail(1)),
onBranch: (thatValue, thatForest) => {
const valueOrder = orderA(selfValue, thatValue)
if (valueOrder !== 0) {
return Effect.fail(valueOrder)
}
if (selfForest.length < thatForest.length) {
return Effect.fail(-1)
} else if (selfForest.length > thatForest.length) {
return Effect.fail(1)
}
return Effect.suspend(() =>
pipe(
selfForest,
Array.zip(thatForest),
Effect.forEach(order),
Effect.map(K(void {})),
),
)
},
}),
),
}),
)
}
|