import { concreteSortedMap } from "@tsplus/stdlib/collections/SortedMap/_internal/SortedMapInternal" /** * A generator which chooses one of the given generators according to their * weights. For example, the following generator will generate 90% true and * 10% false values. * * @tsplus static effect/core/testing/Gen.Ops weighted */ export function weighted(...gens: Array, number]>): Gen { const sum = gens.reduce((acc, [_, n]) => acc + n, 0) const [map, _] = gens.reduce( ([map, acc], [gen, d]) => (acc + d) / sum > acc / sum ? [map.set((acc + d) / sum, gen), acc + d] : [map, acc], [SortedMap.empty>(Ord.number), 0] ) return Gen.uniform().flatMap((n) => getGreaterThanEqual(map, n).getOrElse(() => { throw new NoSuchElement() }) ) } function getGreaterThanEqual(map: SortedMap, key: K): Maybe { concreteSortedMap(map) const cmp = map.tree.ord.compare let n = map.tree.root let lastValue = Maybe.empty() while (n) { const d = cmp(key, n.key) if (d <= 0) { lastValue = Maybe.some(n.value) n = n.left } else { if (lastValue._tag === "Some") { break } n = n.right } } return lastValue }