fp-ts函數語言程式設計 - either, left & right
阿新 • • 發佈:2021-10-13
前兩篇的快速連結
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/