All files / src/draw/partF instances.ts

100% Statements 65/65
100% Branches 12/12
100% Functions 5/5
100% Lines 65/65

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 1131x         1x 1x 1x 1x                       1x 1x 1x 3676x 3676x 3676x 3676x 3676x 3676x 728x 728x 728x 728x 3676x 1205x 1205x 1205x 1205x 3676x 3676x 1x             1x             1x     376x   376x 376x 376x 3405x 3405x 3405x 376x             1x             1x   1x 1x 3405x 3405x 3405x       3405x 3405x   3405x 3405x 3405x 3405x 3405x 3405x 643x 643x 643x 643x 643x 3405x 1136x 1136x 1136x 1136x 1136x 3405x 3405x 3405x  
import {
  Applicative,
  Covariant as CO,
  Traversable as TA,
} from '@effect/typeclass'
import {Traversable as ArrayTraversable} from '@effect/typeclass/data/Array'
import {Array, flow, Function, HKT, pipe} from 'effect'
import {emptyF, textF} from './data.js'
import {
  ColumnF,
  matchPartF,
  RowF,
  type PartF,
  type PartFTypeLambda,
} from './types.js'
 
/**
 * @category drawing
 * @function
 */
export const map: CO.Covariant<PartFTypeLambda>['map'] = Function.dual(
  2,
  <A, B>(fa: PartF<A>, f: (a: A) => B) =>
    pipe(
      fa,
      matchPartF<A, PartF<B>>(
        emptyF,
        show => textF(show),
        ({cells, ...rest}): RowF<B> =>
          RowF({
            ...rest,
            cells: pipe(cells, Array.map(f)),
          }),
        ({cells, ...rest}): ColumnF<B> =>
          ColumnF({
            ...rest,
            cells: pipe(cells, Array.map(f)),
          }),
      ),
    ),
)
 
/**
 * `Covariant` instance for {@link PartF}.
 * @category drawing
 * @function
 */
export const imap = CO.imap<PartFTypeLambda>(map)
 
/**
 * `Covariant` instance for {@link PartF}.
 * @category drawing
 * @function
 */
export const traverse: TA.Traversable<PartFTypeLambda>['traverse'] = <
  F extends HKT.TypeLambda,
>(
  F: Applicative.Applicative<F>,
) =>
  Function.dual(
    2,
    <A, B>(
      tfa: PartF<A>,
      f: (a: A) => HKT.Kind<F, unknown, unknown, never, B>,
    ) => pipe(tfa, map(f), sequenceParts(F)),
  )
 
/**
 * `Covariant` instance for {@link PartF}.
 * @category drawing
 * @category instances
 */
export const Covariant: CO.Covariant<PartFTypeLambda> = {map, imap}
 
/**
 * `Traversable` instance for {@link PartF}.
 * @category drawing
 * @category instances
 */
export const Traversable: TA.Traversable<PartFTypeLambda> = {traverse}
 
const sequenceParts =
  <F extends HKT.TypeLambda>(F: Applicative.Applicative<F>) =>
  <A>(
    partF: PartF<HKT.Kind<F, unknown, unknown, never, A>>,
  ): HKT.Kind<F, unknown, unknown, never, PartF<A>> => {
    type Fa = HKT.Kind<F, unknown, unknown, never, A>
    type FPa = HKT.Kind<F, unknown, unknown, never, PartF<A>>
 
    const traverse = TA.sequence(ArrayTraversable)(F)
    const map = F.map<readonly A[], PartF<A>>
 
    return pipe(
      partF,
      matchPartF(
        F.of<PartF<A>>(emptyF),
        flow(textF, F.of<PartF<A>>),
        ({cells, ...rest}: RowF<Fa>): FPa =>
          pipe(
            cells,
            traverse,
            map(cells => RowF({...rest, cells: [...cells]})),
          ),
        ({cells, ...rest}: ColumnF<Fa>): FPa =>
          pipe(
            cells,
            traverse,
            map(cells => ColumnF({...rest, cells: [...cells]})),
          ),
      ),
    )
  }