繁体   English   中英

将 fp-ts TaskEither 与右侧的 Either 连接起来

[英]Chain fp-ts TaskEither with Either in right

我有 2 个嵌套请求的流程,其中可能是 3 个不同的结果:

  1. 请求之一返回错误
  2. 用户不是匿名的,返回 Profile
  3. 用户是匿名的,返回 false

两个请求都可能引发错误,因此实现TaskEither

const isAuth = ():TE.TaskEither<Error, E.Either<true, false>>  
   => TE.tryCatch(() => Promise(...), E.toError)
const getProfile = ():TE.TaskEither<Error, Profile>  
   => TE.tryCatch(() => Promise(...), E.toError)

第一个请求返回用户授权的 boolean 状态。 如果用户被授权,第二个请求会加载用户配置文件。

作为回报,我想获得下一个签名,错误或匿名/配置文件:

E.Either<Error, E.Either<false, Profile>>

我试图这样做:

pipe(
    isAuth()
    TE.chain(item => pipe(
      TE.fromEither(item),
      TE.mapLeft(() => Error('Anonimous')),
      TE.chain(getProfile)
    ))
  )

但作为回报,我得到E.Either<Error, Profile> ,这并不方便,因为我必须手动从Error中提取Anonymous状态。

如何解决这个问题?

不知道您是否过度简化了实际代码,但E.Either<true, false>boolean同构,所以让我们坚持使用更简单的东西。

declare const isAuth: () => TE.TaskEither<Error, boolean>;
declare const getProfile: () => TE.TaskEither<Error, Profile>;

然后根据是否已验证添加条件分支并包装 getProfile 的结果:

pipe(
  isAuth(),
  TE.chain(authed => authed 
    ? pipe(getProfile(), TE.map(E.right)) // wrap the returned value of `getProfile` in `Either` inside the `TaskEither`
    : TE.right(E.left(false))
  )
)

此表达式的类型为TaskEither<Error, Either<false, Profile>> 您可能需要为其添加一些类型注释才能正确进行类型检查,我自己还没有运行代码。

编辑:

您可能需要提取名为 function 的 lambda 以获得正确的类型,如下所示:

const tryGetProfile: (authed: boolean) => TE.TaskEither<Error, E.Either<false, Profile>> = authed
  ? pipe(getProfile(), TE.map(E.right))
  : TE.right(E.left(false));

const result: TE.TaskEither<Error, E.Either<false, Profile>> = pipe(
  isAuth(),
  TE.chain(tryGetProfile)
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM