例外のセマンティクスは非常に制限されています。それらは、スローされた場所、または直接の呼び出しスタックで正確に処理する必要があります。コンパイル時に、プログラマーがそれを忘れた場合は表示されません。
これを、エラーがResultsまたはMaybesとしてエンコードされるElmと比較してください。どちらも値です。つまり、エラーを処理しないと、コンパイラエラーが発生します。変数またはコレクションに保存して、処理を都合の良い時間に延期することができます。非常によく似たtry-catchブロックをあちこちで繰り返す代わりに、アプリケーション固有の方法でエラーを処理する関数を作成できます。それらをすべての部分が成功した場合にのみ成功する計算にチェーンでき、1つのtryブロックに詰め込む必要はありません。組み込みの構文による制限はありません。
これは「例外を飲み込む」ようなものではありません。型システムでエラー条件を明示し、それらを処理するためのはるかに柔軟な代替セマンティクスを提供しています。
次の例を考えてみましょう。動作を確認したい場合は、これをhttp://elm-lang.org/tryに貼り付けることができます。
import Html exposing (Html, Attribute, beginnerProgram, text, div, input)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
import String
main =
beginnerProgram { model = "", view = view, update = update }
-- UPDATE
type Msg = NewContent String
update (NewContent content) oldContent =
content
getDefault = Result.withDefault "Please enter an integer"
double = Result.map (\x -> x*2)
calculate = String.toInt >> double >> Result.map toString >> getDefault
-- VIEW
view content =
div []
[ input [ placeholder "Number to double", onInput NewContent, myStyle ] []
, div [ myStyle ] [ text (calculate content) ]
]
myStyle =
style
[ ("width", "100%")
, ("height", "40px")
, ("padding", "10px 0")
, ("font-size", "2em")
, ("text-align", "center")
]
関数String.toInt
内calculate
で失敗する可能性があることに注意してください。Javaでは、これによりランタイム例外がスローされる可能性があります。ユーザー入力を読み取るため、かなりの可能性があります。代わりに、エルムはを返すことで対処するように強制しますがResult
、すぐに対処する必要はないことに注意してください。私は入力を倍増し、文字列に変換し、することができ、その後に不正な入力をチェックするgetDefault
機能。この場所は、エラーが発生したポイントやコールスタックの上方よりも、チェックに適しています。
コンパイラが私たちの手を強制する方法も、Javaのチェックされた例外よりもはるかにきめ細かいです。必要なResult.withDefault
値を抽出するなど、非常に特殊な関数を使用する必要があります。技術的にはそのようなメカニズムを悪用する可能性がありますが、あまり意味はありません。置くべき適切なデフォルト/エラーメッセージを知るまで決定を延期できるので、それを使用しない理由はありません。