fp-ts
TypeScriptで関数型プログラミングをするlibrary
開発者はGiulio Canti
Effect-TSにmergeされる予定
Announcement: following the official decision to merge the fp-ts project with the Effect-TS ecosystem, active development has been transferred to the repository https://github.com/Effect-TS/data. ref
@EffectTS_: The news is out! 📢
We have made the decision to unite and collaborate on *Effect* as a generational project that aims to create a more cohesive and powerful ecosystem of libraries that are accessible and useful to developers of all levels.
fp-tsの型クラス
fp-tsの各moduleのdocumentの読み方
github
docs
型
Task型
TaskEither型
etc.
#WIP
import
2種類ある
code:ts
import { Option } from 'fp-ts/lib/Option'; // CommonJS
import { Option } from 'fp-ts/es6/Option'; // ESModule
ESModuleの方にするとTreeShakingによりバンドルサイズが削減できる
Node.js上で動かすならCommonJSを使う
pipe
code:ts
import * as O from 'fp-ts/lib/Option'
import { identity } from 'fp-ts/lib/function'
import { pipeable } from 'fp-ts'
pipeable.pipe(
O.some(42), // O.Option<number>
O.chain(n => n === 42 ? O.some('Answer to Everything') : O.none), // (ma: O.Option<number>) => O.Option<string>
O.fold(() => 'No Answer', identity) // (ma: O.Option<string>) => string
) // string
Bounded Types
https://dev.to/derp/bounded-types-in-fp-ts-7db
数値型で例えば18~100の間だけであることを保証する
例
io-tsとfp-tsを使ったTwitter APIのSample
https://github.com/OliverJAsh/twitter-api-ts
#??
関数型プログラミングできるのは良いのだが、プロダクト全体がfp-tsに大依存してしまいそうで怖い
プロダクト全体で使うものなのか、それとも、ロジックゴリゴリのところで局所的に使うのかどっちなんだろう
例えばparserとか、RESTとか
IO時にResult型使うとかはありそうだが
Monadとか実際どこで使うんだ
普通にTS書いているよりも冗長になる部分もあると思うので、型的にかなりメリットがないと入れる意味があるのかどうかわからないmrsekut.icon
別に、関数型プログラミングがしたいわけではない
型安全で、楽に、簡素に書ける方を選びたい
「fp-ts便利!」という記事ではなく、普通のTSの書き方とfp-tsの比較という記事を書くべき
似たライブラリ
fp-ts-contrib
NeverThrow
参考
Monad in TypeScript - DEV Community 👩‍💻👨‍💻
fp-tsの紹介
https://gcanti.github.io/fp-ts/guides/purescript.html
pursとfp-tsの差異の列挙
学ぶ順序
型クラスの概念をまず理解する
その上で、個々の型クラスの役割を知る
型クラスは色々定義されているので、順々に見ていくとモチベが下がるかもしれない
であれば、個別の型のページを見つつ、そのinstancesに書かれている型クラスを順に学んで行けば良いかも
https://gcanti.github.io/fp-ts/learning-resources/
Eitherのerrorを積み重ねる
code:ts
import * as E from 'fp-ts/lib/Either';
import { sequenceT } from 'fp-ts/lib/Apply';
import * as A from 'fp-ts/lib/Array';
const hoge = E.getApplicativeValidation(A.getMonoid<string>());
console.log(sequenceT(hoge)(E.left('a'), E.left('b')));
// { _tag: 'Left', left: 'a', 'b' }
https://zanza00.gitbook.io/learn-fp-ts/introduction
https://itnext.io/fp-ts-in-action-d7d5f41c4858
https://collectednotes.com/gillchristian/enough-fp-ts-to-work-with-io-ts
https://rlee.dev/practical-guide-to-fp-ts-part-1
https://marcel.is/fp-ts/