0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

effect-tsでなるべく機能を使わない

Last updated at Posted at 2025-10-22

いろいろ試した結果
effect-tsのような書き方を排除する書き方を採用したくなった

基本的に使うのは以下のみぐらいがいい気がする

  • Effect.succeed
  • Effect.fail
  • Effect.gen(function*() { ... })
  • Effect.either( ... )

成功と失敗が2つある関数の場合

普通に成功時の値と失敗時の値を変数で用意して、最後にEffect.succeedかEffect.failで返す

const InputData = Schema.Struct({
  route: Schema.Tuple(Schema.Number, Schema.Number)
})
type InputDataType = typeof InputData.Type

// ---- 料金計算 ----
function routeFareCalculation(input: InputDataType) {
  const [start, end] = input.route

  if (start === end) {
    const ng_result = "開始位置と終了位置が同じです"
    return Effect.fail(ng_result)
  } else {
    const ok_result = Math.abs(start - end)
    return Effect.succeed(ok_result)
  }
}

成功の場合のみを扱う後続の関数

Either型を外部に出さないで成功した時にデータとして表現したい形のみを使用する

// ---- OKデータ処理 ----
const RouteAndFareData = Schema.Struct({
  route: Schema.Tuple(Schema.Number, Schema.Number),
  fare: Schema.Number
})
type RouteAndFareDataType = typeof RouteAndFareData.Type

function displayRouteAndFare(routeAndFare: RouteAndFareDataType) {
  const [start, end] = routeAndFare.route
  console.log(`start: ${start}, end: ${end}, fare: ${routeAndFare.fare}`)
}

失敗の場合のみを扱う後続の関数

Either型を外部に出さないで失敗した時にデータとして表現したい形のみを使用する

// ---- NGデータ処理 ----
type ErrorMessage = string
function displayError(error: ErrorMessage) {
  console.log(`error: ${error}`)
}

全体

programでそれぞれの関数の結果をEither型で取得したり、後続用のデータを作成したりする
こういうつなぎのための関数が1つは必要で、そこでEffect.gen(function*() { ... }) を使う
Effect.either( ... ) で成功か失敗かの値を取得する

全ソース

import { Effect, Either, Schema } from "effect"

const InputData = Schema.Struct({
  route: Schema.Tuple(Schema.Number, Schema.Number)
})
type InputDataType = typeof InputData.Type

// ---- 料金計算 ----
function routeFareCalculation(input: InputDataType) {
  const [start, end] = input.route

  if (start === end) {
    const ng_result = "開始位置と終了位置が同じです"
    return Effect.fail(ng_result)
  } else {
    const ok_result = Math.abs(start - end)
    return Effect.succeed(ok_result)
  }
}

// ---- OKデータ処理 ----
const RouteAndFareData = Schema.Struct({
  route: Schema.Tuple(Schema.Number, Schema.Number),
  fare: Schema.Number
})
type RouteAndFareDataType = typeof RouteAndFareData.Type

function displayRouteAndFare(routeAndFare: RouteAndFareDataType) {
  const [start, end] = routeAndFare.route
  console.log(`start: ${start}, end: ${end}, fare: ${routeAndFare.fare}`)
}

// ---- NGデータ処理 ----
type ErrorMessage = string
function displayError(error: ErrorMessage) {
  console.log(`error: ${error}`)
}

const program = Effect.gen(function*() {
  const input = InputData.make({ route: [123, 456] }) // ok
//   const input = InputData.make({ route: [456, 123] }) // ok
//   const input = InputData.make({ route: [111, 111] }) // ng

  const result = yield* Effect.either(routeFareCalculation(input))

  if (Either.isRight(result)) {
    const ok_result = result.right
    const routeAndFare = RouteAndFareData.make({
      route: input.route,
      fare: ok_result
    })
    displayRouteAndFare(routeAndFare)
  } else {
    const ng_result = result.left
    displayError(ng_result)
  }
})

Effect.runSync(program)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?