All files / src/laws/typeclass/parameterized SemiAlternative.ts

100% Statements 39/39
100% Branches 3/3
100% Functions 1/1
100% Lines 39/39

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 661x   1x   1x   1x           1x   1x 8x 8x   8x 8x 8x   8x 8x 8x 8x 8x 8x 8x 800x 800x 800x 800x 8x   8x 8x 8x 8x 8x 8x 8x 603x 603x 603x 603x 8x 8x 8x 8x 8x                              
import {Law, addLawSets, lawTests} from '#law'
import {SemiAlternative as SA} from '@effect/typeclass'
import {pipe} from 'effect'
import type {TypeLambda} from 'effect/HKT'
import {covariantLaws} from './Covariant.js'
import type {BuildParameterized} from './given.js'
import {unfoldGiven} from './given.js'
 
/**
 * Typeclass laws for `SemiAlternative`.
 * @category typeclass laws
 */
export const semiAlternativeLaws: BuildParameterized<
  SemiAlternativeTypeLambda
> = (given, suffix?) => {
  const {F, equalsFa, fa} = unfoldGiven(given),
    {coproduct, coproductMany} = F
 
  return pipe(
    lawTests(
      `SemiAlternative${suffix ?? ''}`,
 
      Law(
        'associativity',
        '(fa₁ ⊕ fa₂) ⊕ fa₃ = fa₁ ⊕ (fa₂ ⊕ fa₃)',
        fa,
        fa,
        fa,
      )((fa1, fa2, fa3) =>
        equalsFa(
          coproduct(coproduct(fa1, fa2), fa3),
          coproduct(fa1, coproduct(fa2, fa3)),
        ),
      ),
 
      Law(
        'coproductMany associativity',
        'coproductMany(fa₁ ⊕ [fa₂, fa₃]) = coproduct(fa₁, coproduct(fa₂, fa₃))',
        fa,
        fa,
        fa,
      )((fa1, fa2, fa3) =>
        equalsFa(
          coproductMany(fa1, [fa2, fa3]),
          coproduct(fa1, coproduct(fa2, fa3)),
        ),
      ),
    ),
    pipe(given, covariantLaws, addLawSets),
  )
}
 
/**
 * Type lambda for the `SemiAlternative` typeclass.
 * @category type lambda
 */
export interface SemiAlternativeTypeLambda extends TypeLambda {
  readonly type: SA.SemiAlternative<this['Target'] & TypeLambda>
}
 
declare module './given.js' {
  interface ParameterizedLambdas {
    SemiAlternative: SemiAlternativeTypeLambda
  }
}