How to operate on a reader within a pipe?

32 Views Asked by At

I am trying to implement a reader. I have the following code (from Advent of Code 2023 day 2):

import * as A from "fp-ts/Array";
import * as Rc from "fp-ts/Record";
import * as Rd from "fp-ts/Reader";
import { pipe } from "fp-ts/function";

type Set = Record<string, number>;

type Game = {
  number: number;
  sets: Array<Set>;
};

const availableCubes: Set = {
  red: 12,
  green: 13,
  blue: 14,
};

function validateSet(set: Set): Rd.Reader<Set, boolean> {
  function res(availableCubes: Set): boolean {
    return pipe(
      set,
      Rc.keys,
      A.map((k) => set[k] < availableCubes[k]),
      A.every((x) => x)
    );
  }
  return res;
}

function validateGame(game: Game): Rd.Reader<Set, boolean> {
  const res = pipe(
    game,
    (x) => x.sets,
    A.map((x) => validateSet(x)),
    A.every((x) => x)
  );
  return res;
}

validateSet takes a Set and returns a Reader<Set, boolean> where the Set is the dependency availableCubes and the bool represents the validity of the set.

validateGame validates each set in the game by mapping over the array of sets with validateSet and checking that they are all true.

My problem is that validateSet returns a Reader, not a bool. So validateGame will not compile because of the following line, which treats as x a bool.

    A.every((x) => x)

How can I change my code so that I can perform the above operation where x is a Reader<Set, bool> and not a bool?

0

There are 0 best solutions below