fp-ts函数式编程 - either, left & right

前两篇的快速链接
pipe与flow
option, map, flatten 与 chain

Either (fp-ts/lib/Either) 用来表示一个同步操作,该操作可能成功也可能失败。TaskEither是Either的异步版本,后面的随笔再作介绍。
Right、Left是Either的衍生类(子类),分别表示成功(Right),失败(Left)的情况。其定义可以近似认为如下:

type Either<E, A> = Left<E> | Right<A>

export interface Left<E> {
  readonly _tag: 'Left'
  readonly left: E
}

export interface Right<A> {
  readonly _tag: 'Right'
  readonly right: A
}

Either在函数式编程中的主要作用是捕获异常状态,由于不能在pipe(管道)处理序列中加入try/catch,所以只能用Either来处理异常并中断管道方法的执行。
下面的代码示例有两个validate方法,验证姓名、密码。如果都通过,则执行最后的SayHello,否则后续方法不会被执行。

import { pipe } from "fp-ts/lib/function";
import { Either, left, right, chain, map} from "fp-ts/lib/Either";

type ErrorType =
  "invalid name"
  | "invalid password"
  | "others";

type UserInfo = {
    name: string,
    password: string,
    age?: number
}

function ValidateName(user: UserInfo): Either<ErrorType, UserInfo> {
    return  user.name.length > 3? right(user) : left("invalid name")
}
   
function ValidatePassword(user: UserInfo): Either<ErrorType, UserInfo> {
    return  user.password.length > 3? right(user) : left("invalid password")
}

function SayHello(user: UserInfo) {
    console.log(`hello ${user.name}`);
}

pipe(
    { name:'Andy', password:'123456'}, 
    ValidateName,  
    chain(ValidatePassword),
    map(SayHello)
);

pipe(
    { name:'Andy', password:'12'}, 
    ValidateName,  
    chain(ValidatePassword),
    map(SayHello)
);

使用ts-node命令执行后,会看到只有一行hello Andy的输出。证明了第二个pipe,由于validate返回left,则中断了后续代码的执行。

参考
https://dev.to/ryanleecode/practical-guide-to-fp-ts-p3-task-either-taskeither-2hpl
http://www.troikatech.com/blog/2020/09/24/fp-ts-error-handling-the-functional-way/

posted @ 2021-10-13 11:40  老胡Andy  阅读(773)  评论(0编辑  收藏  举报