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 | 45x 7x 45x 14x 14x 14x 14x 14x 14x 14x 14x 1442x 14x 1400x 1415x 1400x 1400x 1400x | import {addLawSets, Law, lawTests} from '#law'
import {Foldable as FO} from '@effect/typeclass'
import {Monad as identityMonad} from '@effect/typeclass/data/Identity'
import {Foldable as optionFoldable} from '@effect/typeclass/data/Option'
import {Array as AR, identity, pipe} from 'effect'
import type {TypeLambda} from 'effect/HKT'
import {UnderlyingArbitrary, UnderlyingEquivalence} from '../../../arbitrary.js'
import {Endo} from '../../../typeclass.js'
import {withOuterOption} from './compose.js'
import type {BuildParameterized} from './given.js'
import {unfoldGiven} from './given.js'
import {BuildInternal} from './internal.js'
/**
* Typeclass laws for `Foldable`.
* @category typeclass laws
*/
export const foldableLaws: BuildParameterized<FoldableTypeLambda> = (
given,
suffix?,
) =>
pipe(
buildLaws(`Foldable${suffix ?? ''}`, given),
addLawSets(
buildLaws(...withOuterOption('Foldable', given, optionFoldable)),
),
)
const buildLaws: BuildInternal<FoldableTypeLambda> = (name, given) => {
const {Monoid: monoid, F, fa, b, bab, equalsA, equalsB} = unfoldGiven(given),
{reduce} = F,
toArray = FO.toArray(F),
equalsArrayA = AR.getEquivalence(equalsA),
reduceKind = FO.reduceKind(F),
{empty, combine} = monoid,
combineMap = pipe(monoid, FO.combineMap(F)),
arrayAppend = <T>(accumulator: T[], value: T): T[] =>
AR.append(accumulator, value)
type A = UnderlyingEquivalence<typeof equalsA>
type B = UnderlyingArbitrary<typeof b>
return pipe(
lawTests(
name,
Law(
'reduce',
'reduce(b, bab) = combineMap(Monoid<Endo<B>>)(a ⇒ b ⇒ bab(b, a))',
fa,
b,
bab,
)((fa, empty, combine) =>
equalsB(
pipe(fa, reduce(empty, combine)),
pipe(
empty,
pipe(
fa,
pipe(
Endo.getMonoid<B>(),
FO.combineMap(F),
)(a => b => combine(b, a)),
),
),
),
),
Law(
'combineMap',
'reduce(∅, ⊕) = combineMap(Monoid)(id)',
fa,
)(fa =>
equalsA(
pipe(fa, reduce(empty, combine)),
pipe(fa, combineMap(identity)),
),
),
Law(
'reduceKind',
'reduceKind(Monad<Id>) = reduce',
fa,
b,
bab,
)((fa, b, bab) =>
equalsB(
pipe(fa, reduceKind(identityMonad)(b, bab)),
pipe(fa, reduce(b, bab)),
),
),
Law(
'toArray',
'toArray = reduce([], Array.append)',
fa,
)(fa =>
equalsArrayA(toArray(fa), pipe(fa, reduce([] as A[], arrayAppend))),
),
),
)
}
/**
* Type lambda for the `Foldable` typeclass.
* @category type lambda
*/
export interface FoldableTypeLambda extends TypeLambda {
readonly type: FO.Foldable<this['Target'] & TypeLambda>
}
declare module './given.js' {
interface ParameterizedLambdas {
Foldable: FoldableTypeLambda
}
}
|