0

I was trying to start using fp-ts and I had a really hard time with side-effects. I wrote a little test program that will read a file, print the file to screen and return an Either<Error, string>.

I used the basic do notation as an example and ended up with a code that looks somthing like that

const program = pipe(
    TE.tryCatch(() => readFile(), () => new Error('Failed to read file')),
    TE.chainFirst((text) => pipe(log(text), TE.fromIO)),
);

This code compiles, but typescript infers that the program variable gets the type TE.TaskEither<unknown, string> and I was expecting the type TE.TaskEither<Error, string>.

Is there a way to keep the error type inside the TaskEither? Or am I using this librery all wrong?

p.s I am using fp-ts version 2.8.6

nhruo
  • 79
  • 7

1 Answers1

3

You can use chainFirstIOK:

export declare const chainFirstIOK: <A, B>(f: (a: A) => IO<B>) => <E>(first: TaskEither<E, A>) => TaskEither<E, A>
const program = pipe(
    TE.tryCatch(() => readFile(), () => new Error('Failed to read file')),
    TE.chainFirstIOK((text) => pipe(log(text), TE.fromIO)),
);

Now returns TaskEither<Error, string>.

You can also simplify it even more using flow:

const program = pipe(
  TE.tryCatch(() => readFile(), () => new Error('Failed to read file')),
  TE.chainFirstIOK(flow(log, TE.fromIO)),
);
kibe
  • 90
  • 1
  • 8
  • 26
  • I see this function is new to 2.10 I'll update my fp-ts version. And One more thing, what does the K stands for in chain first IO? – nhruo Jun 16 '21 at 19:18
  • 1
    It stands for Kleisli - you can read about the K suffix here - https://gcanti.github.io/fp-ts/guides/code-conventions.html#what-a-k-suffix-means-eg-fromeitherk-or-chaineitherk – cdimitroulas Jun 23 '21 at 14:41