Error_Handling - kzono/study_haskell GitHub Wiki

エラー処理の方法

プログラミング言語によってエラー処理機構は異なる。それぞれの長所・短所について明確にしたい。

  • 単純な戻り値
  • 例外処理機構(Exception の throw, try-catch)
  • 代数的データ型(maybe/option/optional, either, パターンマッチ)

例外処理の問題点

JavaScript関数型プログラミングより

関数型プログラミングと例外は相容れない。

  • 関数の合成やチェーン化ができない
  • 参照透過性が損なわれる(関数の計算結果が単一の予測可能な値にならない)
  • 予期しないスタックの巻き戻しは、副作用が発生する原因となる
  • 複数のエラー条件が発生して例外処理が入れ子になるような場合、扱いづらい

Scala関数型デザイン&プログラミングより

失敗や例外を通常の値で表し、エラー処理とリカバリに共通するパターンを高階関数として抽出する。 高階関数を使うことにより、「エラー処理のロジックを一本化」という例外の主な利点も維持できる。

  • 例外は参照透過性を失わせ、コンテキストへの依存をもたらすため、結果を予想することが難しくなる。例外はエラー処理にのみ使用すべきであり、制御フローには使用すべきではない。
  • 例外は型安全ではない

代数的データ型(Algebraic data type)

戻り値として正常値または異常値を入れられる型として、代数的データ型を使う。

C++, Java, Scala は例外を使うこともできるし、例外を使わないエラー処理を行うこともできる。 一方、Haskell や Rust にはそもそも例外機構がないので例外を使うことができない。

多値返し

Go や Elixer は戻り値として(正常値, 成功 or 失敗)といった値のセットを返す。