Error_Handling - kzono/study_haskell GitHub Wiki
エラー処理の方法
プログラミング言語によってエラー処理機構は異なる。それぞれの長所・短所について明確にしたい。
- 単純な戻り値
- 例外処理機構(Exception の throw, try-catch)
- 代数的データ型(maybe/option/optional, either, パターンマッチ)
例外処理の問題点
関数型プログラミングと例外は相容れない。
- 関数の合成やチェーン化ができない
- 参照透過性が損なわれる(関数の計算結果が単一の予測可能な値にならない)
- 予期しないスタックの巻き戻しは、副作用が発生する原因となる
- 複数のエラー条件が発生して例外処理が入れ子になるような場合、扱いづらい
失敗や例外を通常の値で表し、エラー処理とリカバリに共通するパターンを高階関数として抽出する。 高階関数を使うことにより、「エラー処理のロジックを一本化」という例外の主な利点も維持できる。
- 例外は参照透過性を失わせ、コンテキストへの依存をもたらすため、結果を予想することが難しくなる。例外はエラー処理にのみ使用すべきであり、制御フローには使用すべきではない。
- 例外は型安全ではない
代数的データ型(Algebraic data type)
戻り値として正常値または異常値を入れられる型として、代数的データ型を使う。
- Haskell : maybe, either
- Scala : Option, Either
- C++ : std::optional
- Java : Optional
- Rust : Option, Result
C++, Java, Scala は例外を使うこともできるし、例外を使わないエラー処理を行うこともできる。 一方、Haskell や Rust にはそもそも例外機構がないので例外を使うことができない。
多値返し
Go や Elixer は戻り値として(正常値, 成功 or 失敗)といった値のセットを返す。
- GolangのErrorについて分かったこと
- Elixer school エラーハンドリング