Learn fp-ts
  • Learn fp-ts
  • Introduction
  • Data Types
  • Code conventions
  • Option
    • Type guards
    • Comparison with vanilla typescript
  • Either
    • ParseJson
  • TaskEither
    • TaskEither and io-ts
Powered by GitBook
On this page

Was this helpful?

Either

it's Either pizza or ice-cream

PreviousComparison with vanilla typescriptNextParseJson

Last updated 4 years ago

Was this helpful?

Either represent one value or the other. What this means is that the values are mutually exclusive, or you have a Left<A> or a Right<B>. Thus the representation of this data type is with two generics Either<A, B>.

It's useful to this that Option is a value that maybe is present, Either is a value that perhaps is present or some kind of error is present. This is usually used to represent the result of something that can fail, and because Right is Right when we use map the function is applied to the Right, if you want to map the error we can use mapLeft. In other words we can say that Either is Right biased.

Think the last time that you needed to use a `Try catch` block. If you need to convey the meaning of the failure, that's a good indicator of potential use for Either.

One of the most prominent utilization of Either is JSON.parse. If the data is malformed, it will throw an exception breaking the referential transparency. It's such a common utilization that is already present in fp-ts

We are now implementing that function from scratch. Since the original function can throw we need to use a try catch block. Since we need to think about the error for now we use a plain Error for that. Also we don't know anything about the data if parsed correctly hence we use unknown.

import * as E from 'fp-ts/lib/Either';

function parseJson(str: string): E.Either<Error,unknown> {
    try {
        return E.right(JSON.parse(str))
    } catch (e) {
        return E.left(e instanceof Error ? e : new Error('unknown error'))
    }
}

Writing every time the try catch block gets boring pretty fast. Fortunately there is a function for the occasion inside Either that is called so let's refactor a bit.

import * as E from 'fp-ts/lib/Either';

function parseJson(str: string): E.Either<Error,unknown> {
    return E.tryCatch(() => JSON.parse(str), e => e instanceof Error ? e : new Error('unknown error'))
}
import * as E from 'fp-ts/lib/Either';

function parseJson(str: string): E.Either<Error,unknown> {
    return E.tryCatch(() => JSON.parse(str), e => E.toError(e))
}

Now we can improve it by dealing with the error using another utility called

Now if we look at the source we can see that it's basically what we wrote

Either#parseJson
tryCatch
toError
code of parseJson