Effect-TS
Effect
Effect is a powerful TypeScript library designed to help developers easily create complex, synchronous, and asynchronous programs.
One of the key features that sets Effect apart is how it leverages structured concurrency to provide features such as async cancellation and safe resource management, making it easier to build robust, scalable, and efficient programs. effectが正式名称らしいが紛らわしいので-tsをつけて書く
まあgithubのorgnameはEffect-TSだし
fp-ts的なやつ?
なんか良さげな匂いがある
code:ts
type Effect<Success, Error, Requirements> = (
context: Context<Requirements>
) => Error | Success
成功、失敗、依存が型で表せるのはいい気がする
effect essentials
effectの作成
実行
run{Sync,Promise}{,Exit}
runFork
基本の構成要素、他のやつはこの上で作られてる。
observeやinterrputのためのfiberを返す
run系はプログラムのedgeによせるとよい
generator
logicをgenで書き、yield*でeffectを扱う
pipeline
map,flatMap, andThen, tap ...
関数型知ってればなんとなく知っとるやつ
感想
generatorでeffect(依存、エラー、正常系の値)を表現するのは面白い
code:ts
import { Effect } from "effect"
const increment = (x: number) => x + 1
const divide = (a: number, b: number): Effect.Effect<never, Error, number> =>
b === 0
? Effect.fail(new Error("Cannot divide by zero"))
: Effect.succeed(a / b)
// $ExpectType Effect<never, never, number>
const task1 = Effect.promise(() => Promise.resolve(10))
// $ExpectType Effect<never, never, number>
const task2 = Effect.promise(() => Promise.resolve(2))
// $ExpectType Effect<never, Error, string>
export const program = Effect.gen(function* (_) {
const a = yield* _(task1)
const b = yield* _(task2)
const n1 = yield* _(divide(a, b))
const n2 = increment(n1)
return Result is: ${n2}
})
Effect.runPromise(program).then(console.log) // Output: "Result is: 6"
しかし、単にresult型と高階関数で記述すれば同じことは実現できるのでは
code:ts
(deps) => (input) => Result<output, error>
generatorの_の関数が無名で謎
これ、pipeの機能もあるみたいで、シンプルじゃない
これアプデで要らなくなったぽい。型推論の都合だったのか分からんが、TSの5.5だかあたりでなんとかなったぽい
Effect-TSをうまく使いこなせれば便利そうな印象があるが、コードが読みやすいかってのと、チームでこれを使えるように伝えられるかとかがむずそう
しかし、認証あたりとかたいていロックインしがちで、開発環境も面倒なことになりがちだったりするので最初っから認証部分のインターフェースを定めて注入するようにすると楽ちんそうだな、という気もする