TL;DR

成功したときの値(Ok)か、失敗したときのエラー(Error)のどちらかを持つ型。F# では標準ライブラリにある判別共用体である。

なぜ必要か

Domain Modeling Made Functional によると、エラーは例外でも扱えるが、Result を使うと「失敗する可能性がある」という事実を型シグネチャで明示できる。

仕組み

F# のドキュメントでは、Result は次のように定義されている。構造体の判別共用体なので、構造的な等価性を持つ。

type Result<'T,'TError> =
    | Ok of ResultValue:'T
    | Error of ErrorValue:'TError

F# のコミュニティでは、Result を使ったエラー処理を Railway-oriented Programming と呼ぶ。Result を返す検証関数どうしは Result.bind でつなげられるので、処理を小さな部品に分けて合成できる。検証の最後には結果をパターンマッチで取り出すことになるので、プログラムの正しさを高められる。

例

Domain Modeling Made Functional では、支払いが失敗しうる処理を次のように表す。エラーの型には、起こりうるエラーのケースを並べた判別共用体を使う。

type PayInvoice =
    UnpaidInvoice -> Payment -> Result<PaidInvoice, PaymentError>

同書の第 6 章では、スマートコンストラクタが無効な値を受け取ったときに Error を返す。

関連

出典