TL;DR
成功したときの値(Ok)か、失敗したときのエラー(Error)のどちらかを持つ型。F# では標準ライブラリにある判別共用体である。
なぜ必要か
Domain Modeling Made Functional によると、エラーは例外でも扱えるが、Result を使うと「失敗する可能性がある」という事実を型シグネチャで明示できる。
仕組み
F# のドキュメントでは、Result は次のように定義されている。構造体の判別共用体なので、構造的な等価性を持つ。
type Result<'T,'TError> =
| Ok of ResultValue:'T
| Error of ErrorValue:'TErrorF# のコミュニティでは、Result を使ったエラー処理を Railway-oriented Programming と呼ぶ。Result を返す検証関数どうしは Result.bind でつなげられるので、処理を小さな部品に分けて合成できる。検証の最後には結果をパターンマッチで取り出すことになるので、プログラムの正しさを高められる。
例
Domain Modeling Made Functional では、支払いが失敗しうる処理を次のように表す。エラーの型には、起こりうるエラーのケースを並べた判別共用体を使う。
type PayInvoice =
UnpaidInvoice -> Payment -> Result<PaidInvoice, PaymentError>同書の第 6 章では、スマートコンストラクタが無効な値を受け取ったときに Error を返す。