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 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 1x 42x 1x 11x 1x 16x 1x 16x 1x 1x 1x 1x 1x 2x 1x 2x 1x 4x 4x 4x 1x 1x 1x 1x 1x 4x 4x 4x 1x 1x 1x 1x 1x | import {map, monoidFold, treeCata, type Tree, type TreeFolder} from '#tree'
import {flow, pipe, type Function} from '#util'
import {Monoid} from '@effect/typeclass'
import * as NumberData from '@effect/typeclass/data/Number'
import {
MonoidMax,
MonoidMin,
MonoidMultiply,
MonoidSum,
} from '@effect/typeclass/data/Number'
/**
* A running average encoded as the _sum_ of all values encountered and the
* _count_ of all values encountered.
* @category ops
* @function
*/
export interface RunningAverage {
numerator: number
denominator: number
}
/**
* A monoid for running a running average.
* @category ops
* @function
*/
export const MonoidAverage: Monoid.Monoid<RunningAverage> = Monoid.struct({
numerator: NumberData.MonoidSum,
denominator: NumberData.MonoidSum,
})
/**
* A starting value for a {@link RunningAverage}.
* @category ops
* @function
*/
export const RunningAverage: RunningAverage = {numerator: 0, denominator: 0}
/**
* Compute a running average for a single level in a numeric tree.
* @category fold
* @function
*/
export const averageFold: TreeFolder<RunningAverage, RunningAverage> = self =>
pipe(self, monoidFold(MonoidAverage))
/**
* Compute a running average for a single level in a numeric tree.
* Sum the nodes of a single level in a numeric tree.
* @category fold
* @function
*/
export const numericSumFold: TreeFolder<number, number> = self =>
pipe(self, monoidFold(MonoidSum))
/**
* Multiply the node values of a single level in a numeric tree.
* @category fold
* @function
*/
export const numericProductFold: TreeFolder<number, number> = self =>
pipe(self, monoidFold(MonoidMultiply))
/**
* Find maximum node value in a level of a numeric tree.
* @category fold
* @function
*/
export const numericMaxFold: TreeFolder<number, number> = self =>
pipe(self, monoidFold(MonoidMax))
/**
* Find minimum node value in a level of a numeric tree.
* @category fold
* @function
*/
export const numericMinFold: TreeFolder<number, number> = self =>
pipe(self, monoidFold(MonoidMin))
/**
* Sum all node values in a numeric tree.
* @category ops
* @function
*/
export const sum: (self: Tree<number>) => number = self =>
pipe(self, treeCata(numericSumFold))
/**
* Multiply all node values in a numeric tree and return the product.
* @category ops
* @function
*/
export const multiply = (tree: Tree<number>): number =>
pipe(tree, treeCata(numericProductFold))
/**
* Find max node value in a numeric tree.
* @example
* import {max, from, of} from 'effect-tree'
*
* expect(max(from(1, of(2), from(3, of(4), of(5))))).toBe(5)
* @category ops
* @function
*/
export const max = (tree: Tree<number>): number =>
pipe(tree, treeCata(numericMaxFold))
/**
* Find min node value in a numeric tree.
* @example
* import {min, from, of} from 'effect-tree'
*
* expect(min(from(1, of(2), from(3, of(4), of(5))))).toBe(1)
* @category ops
* @function
*/
export const min = (tree: Tree<number>): number =>
pipe(tree, treeCata(numericMinFold))
/**
* Collapse the sum and count of a running average into the average value.
* @category ops
* @function
*/
export const computeRunningAverage = ({
numerator,
denominator,
}: RunningAverage) => (denominator === 0 ? 0 : numerator / denominator)
/**
* Update the running average with a new value.
* @category ops
* @function
*/
export const updateRunningAverage =
(newValue: number): Function.EndoOf<RunningAverage> =>
average =>
MonoidAverage.combine(average, {numerator: newValue, denominator: 1})
/**
* Create a new running average from a single sample.
* @category ops
* @function
*/
export const toRunningAverage = (numerator: number): RunningAverage => ({
numerator,
denominator: 1,
})
/**
* Compute the arithmetic mean of all node values in a numeric tree.
* @category ops
* @function
*/
export const average: (self: Tree<number>) => number = flow(
map(toRunningAverage),
treeCata(averageFold),
computeRunningAverage,
)
|