2
3

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を分離して制御する戦略

Posted at

概要

関数型プログラミング(FP)において「副作用(Side Effect)」は設計上の最大の敵である。
だが同時に、副作用を完全に排除することは不可能でもある。

ではどうするべきか?

答えはシンプルだ。

副作用を“抑圧”するのではなく、“分離”し、“制御下”に置く。

本稿では Scala を例に、IO・ログ・例外・状態変更といった副作用をどのように扱い、
どのように構造的に「隔離」するのかを設計の観点から論理的に解説する。


1. 副作用とは何か?

✅ 定義:

外部の状態を変更する、あるいは外部の状態に依存する処理

例:

  • ファイルの読み書き
  • コンソール出力(println
  • DB操作・ネットワークアクセス
  • 乱数・現在時刻取得(非決定性)

2. なぜ副作用が問題なのか?

問題点 説明
テスト困難 同じ入力でも出力が変わる=再現性の欠如
デバッグ困難 状態がどこで・いつ変わったかが曖昧
並行処理の危険性 複数スレッドで副作用が衝突 → データ破壊や不整合が発生
設計の非純粋化 副作用の混入によりロジックがブラックボックス化し、再利用性が落ちる

3. 解法:Effectを「分離」して「扱う」

Scalaにはこの問題に対して明快な解法がある:

IO(副作用)を値として扱う。
Effectを構造として管理する。


4. 実装例:IO モナドによる副作用の構造化

import cats.effect.IO

def readLine: IO[String] = IO(scala.io.StdIn.readLine())
def printLine(msg: String): IO[Unit] = IO(println(msg))

val program: IO[Unit] = for {
  _ <- printLine("名前を入力してください:")
  name <- readLine
  _ <- printLine(s"こんにちは、$name さん!")
} yield ()
  • 副作用は即座に実行されない(遅延評価)
  • 純粋関数の中に副作用を“値”として閉じ込める

5. 設計意図:Effectful と Pure の分離

[pure]     validateName(name: String): Either[Error, Name]
[effect]   readLine(): IO[String]
[effect]   printLine(msg: String): IO[Unit]
  • 純粋ロジック(検証や加工)と
  • Effectfulロジック(入出力や保存)をレイヤーで分ける

→ これによりテストは Pure 部分だけで済み、Effectは統合テストの責務へと移動する


6. 設計判断フロー

① この処理は副作用を含むか? → YES → IOで包んで明示的に扱う

② 処理の本質は値の変換か? → YES → 純粋関数として切り出す

③ いつ副作用が実行されるか制御できているか? → YES → 安定性が高い

④ 副作用の結果に依存しているロジックがあるか? → 分離して境界を定義する

よくある誤解と対策

❌ 副作用は完全に排除すべき?

→ ✅ No。副作用は「必要」だが「無制御で混在」させるべきではない


❌ IOで包むだけでテスト可能になる?

→ ✅ テストは副作用の外側(純粋関数部分)で済ませるのが理想
→ ✅ IO自体のテストにはモック・テストランナーが必要になる


❌ Effectと純粋関数の境界が曖昧

→ ✅ 明確に分けて、「境界はインターフェースとして明示」すべき


結語

関数型プログラミングは副作用を排除しない。
それは**副作用を“明示的に分離し、構造的に制御する思想”**である。

  • 副作用を「値」として管理し
  • 実行タイミングを「制御可能」にし
  • 設計の中で「安全に」組み込めるようにする

関数型設計とは、
“世界を変える行為を、構造の中で閉じ込め、予測可能性に従わせる技術である。”

2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?