Reputation: 55
I was trying to write a localStorage
wrapper in fp-ts when I ran into a roadblock. I want to handle null
values as well as exceptions thrown by localStorage
, so I started with this code:
import * as IOE from "fp-ts/IOEither";
import * as O from "fp-ts/Option";
const getItem = (key: string): IOE.IOEither<Error, O.Option<string>> =>
IOE.tryCatch(
() => O.fromNullable(localStorage.getItem(key)),
E.toError
)
The function above has a return signature of IOEither<Error, Option<string>>
. I want to merge the Option
into the IOEither
, ie, get a IOEither<Error, string>
. How would I achieve this?
P.S. I suppose the above problem is also relevant in the case of TaskEither<Error, Option<string>>
.
Upvotes: 0
Views: 313
Reputation: 14098
You could use something like this:
import * as E from "fp-ts/Either";
import * as IOE from "fp-ts/IOEither";
import * as O from "fp-ts/Option";
import {pipe} from "fp-ts/function";
const getItem = (key: string): IOE.IOEither<Error, string> =>
pipe(
IOE.tryCatch(() => O.fromNullable(localStorage.getItem(key)), E.toError),
IOE.chainEitherK(E.fromOption(() => new Error("key does not exist")))
);
IOE.chainEitherK(f)
is equivalent to IO.map(E.chain(f))
:
export declare const chainEitherK:
<E, A, B>(f: (a: A) => Either<E, B>) => (ma: IOEither<E, A>) => IOEither<E, B>
E.fromOption
converts an Option<A>
into an Either<E, A>
given a default error value if the option is None
:
export declare const fromOption:
<E>(onNone: Lazy<E>) => <A>(ma: Option<A>) => Either<E, A>
Upvotes: 2