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/