Result

Maybe型は失敗するかもしれない単純な関数には役に立ちますが、 なぜ 失敗したかは教えてくれません。あなたのプログラムに何か問題があってコンパイラがNothingとしか言ってくれなかったらどうしましょうか?何が問題だったのか調べて運良く分かるといいですね!

こんなときResult型が役に立ちます。Result型は以下のように定義されます:

type Result error value
  = Ok value
  | Err error

この型のポイントは、問題が起こったときに問題が起こったということだけではなくさらなる情報を提供できるところにあります。この情報はエラーを通知したりエラーに対処したりするのにとても役に立ちます。

エラーを通知する

ひょっとしたら、我々は年齢を入力するサイトを持っているかもしれません。入力された年齢が無効な値ではないか以下のような関数で確認しましょう:

isReasonableAge : String -> Result String Int
isReasonableAge input =
  case String.toInt input of
    Nothing ->
      Err "That is not a number!"

    Just age ->
      if age < 0 then
        Err "Please try again after you are born."

      else if age > 135 then
        Err "Are you some kind of turtle?"

      else
        Ok age

-- isReasonableAge "abc" == Err ...
-- isReasonableAge "-13" == Err ...
-- isReasonableAge "24"  == Ok 24
-- isReasonableAge "150" == Err ...

年齢を確認するだけではなく、ユーザに個々の入力に応じてエラーメッセージを表示することもできます。このようなフィードバックはただNothingを返すよりとてもよいです。

エラーに対処する

Result型はエラーに対処するのにも役に立ちます。役に立っている場所の1つとしてHTTPリクエストを作るところがあります。レフ・トルストイによる小説、 アンナ・カレーニナ の全文を表示したいとしましょう。これを表現しようとすると、HTTPリクエストは結果的にResult Error Stringという型になります。この型はリクエストが成功して全文を得られるか、さまざまな理由で失敗するかを捕捉しています。

type Error
  = BadUrl String
  | Timeout
  | NetworkError
  | BadStatus Int
  | BadBody String

-- Ok "All happy ..." : Result Error String
-- Err Timeout        : Result Error String
-- Err NetworkError   : Result Error String

ここでも先ほどの「エラーを通知する」の例でお見せしたようにより良いエラーメッセージを見せることができますが、それだけではなくエラーが起きたときの対処に使うこともできます。エラーがTimeoutだったら、少し待ってリクエストしなおせばうまくいくでしょう。一方BadStatus 404だったらリクエストしなおす意味はないでしょう。

次の章では実際にHTTPリクエストの作り方を見せていきます。なのですぐさまResult型とError型に再会することになりますよ!

results matching ""

    No results matching ""