const fromPredicateE = <A>(f: () => boolean): Effect.Effect<undefined, PredicateFailedError, A> =>
Effect.suspend(() =>
f()
? Effect.succeed(undefined)
: Effect.fail(new PredicateFailedError({ message: 'Predicate failed' })))
const generateDates = (
timeframe: Timeframe,
startDate: Date,
endDate: Date,
dates: Array<Date> = [],
): Effect.Effect<Array<Date>, Cause.NoSuchElementException | PredicateFailedError, unknown> =>
pipe(
fromPredicateE(() =>
startDate.valueOf() < endDate.valueOf()),
Effect.flatMap(() =>
Effect.succeed(dates)),
Effect.catchAll(() =>
pipe(
Effect.Do,
Effect.bind('ms', () =>
toMs(timeframe)),
Effect.bind('newDate', ({ ms }) =>
add(timeframe, startDate, ms)),
Effect.flatMap(({ newDate }) =>
generateDates(timeframe, newDate, endDate, [...dates, newDate])),
)),
)
const fromPredicateE = <A>(f: () => boolean): Effect.Effect<undefined, PredicateFailedError, A> =>
Effect.suspend(() =>
f()
? Effect.succeed(undefined)
: Effect.fail(new PredicateFailedError({ message: 'Predicate failed' })))
const generateDates = (
timeframe: Timeframe,
startDate: Date,
endDate: Date,
dates: Array<Date> = [],
): Effect.Effect<Array<Date>, Cause.NoSuchElementException | PredicateFailedError, unknown> =>
pipe(
fromPredicateE(() =>
startDate.valueOf() < endDate.valueOf()),
Effect.flatMap(() =>
Effect.succeed(dates)),
Effect.catchAll(() =>
pipe(
Effect.Do,
Effect.bind('ms', () =>
toMs(timeframe)),
Effect.bind('newDate', ({ ms }) =>
add(timeframe, startDate, ms)),
Effect.flatMap(({ newDate }) =>
generateDates(timeframe, newDate, endDate, [...dates, newDate])),
)),
)