将 Option monad 合并到 IOEither 中?

Merging an Option monad into IOEither?

当我 运行 遇到障碍时,我正试图在 fp-ts 中编写一个 localStorage 包装器。我想处理 null 值以及 localStorage 抛出的异常,所以我从这段代码开始:

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
  )

上述函数的 return 签名为 IOEither<Error, Option<string>>。我想将 Option 合并到 IOEither 中,即得到一个 IOEither<Error, string>。我将如何实现这一点?

P.S。我想上述问题也与 TaskEither<Error, Option<string>>.

的情况有关

你可以使用这样的东西:

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) 等同于 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>
如果选项为 None:

,则

E.fromOptionOption<A> 转换为给定默认错误值的 Either<E, A>

export declare const fromOption:
  <E>(onNone: Lazy<E>) => <A>(ma: Option<A>) => Either<E, A>