エラー
error は、effect として流れる型付きエラーをまとめて宣言する短縮構文である。
宣言
yulang
pub error fs_err:
not_found path
denied path
invalid_path pathこの一行で次のものがまとめて生成される。
pub enum fs_err— variant はnot_found path/denied path/invalid_path path。pub act fs_err— variant と同名の operation を持ち、戻り値はnever。impl Throw fs_err—type throws = '[fs_err]とour e.throwを持ち、 対応する operation を発火する。impl Display fs_err— 既定の文字列化(手書きの impl で上書き可能)。fs_err::wrap— companion module 内のヘルパー。error effect をresult値に閉じる。fs_err::up— companion module 内の handler。他の error 型がfrom fs_errを宣言している場合、narrower error をfs_errの effect に 持ち上げる。
constructor と operation は同名
variant 名は データ構築子と effect operation の両方 として使える。 文脈で必要な側が選ばれる。
yulang
my err: fs_err = fs_err::not_found path // 値として構築
fs_err::not_found path // effect として発火fail で投げる
fail は prelude の prefix 演算子で、e.throw を透過的に呼ぶ。
yulang
pub prefix(fail) = \e -> e.throw構築したエラー値を effect として送り出すときに使う。
yulang
my read_text path = fs::read_text path推論型は概ね path -> [fs; fs_err] str の形になり、エラーが effect row に 明示される。
名指しで捕まえる
catch の effect arm は、operation 名を直接書いてエラーを捕まえる。
yulang
catch fs::read_text path:
fs_err::not_found _, _ -> "(missing)"
fs_err::denied _, _ -> "(denied)"
value -> valueYulang のエラー設計は 常に名指しで捕まえる ことを前提にしている。 Display を実行時に dispatch して任意のエラーを文字列化するような型消去の ラッパー(いわゆる anyhow 的なもの)は意図的に採用していない。各エラーは effect row の中で常に具体的な名前で見え、発火地点と捕捉地点が型から分かる。
wrap:値に閉じる
yulang
my read_text_safe path = case fs_err::wrap: fs::read_text path:
result::ok text -> text
result::err err -> err.showE::wrap は、引数 thunk が起こす対応 error effect を捕まえて result _ E を返す。E に from エントリがある場合、wrap はリンクされた narrower error も同時に捕まえ、生成された Cast impl 経由で wrap する。
from による集約
yulang
pub error io_err:
fs from fs_err
parse from parse_errこれにより次のものが生成される。
- variant
io_err::fs fs_errとio_err::parse parse_err Cast fs_err -> io_errとCast parse_err -> io_errの implfs_errとparse_errも同時に捕まえる拡張版io_err::wrap- narrower error を
io_erreffect に変換する handlerio_err::up
yulang
my read_and_parse path =
io_err::up:
my text = fs::read_text path // [fs_err]
parse_json text // [parse_err]
// block 全体の effect は [io_err]基礎的な変換機構については Casts を、catch と effect row の 全般的な話は Effects を参照。