schemeで例外処理ってどうするんだろう?
例えば、与えられたリストをすべてかけた値が欲しいときなどに、0を発見したら処理を中断して0を返すようにしたい。こういうときに、例外が使えると便利そう。
ocamlだとこんな感じ
exception ZeroFound (* 例外の定義 *) let product l = try List.fold_left (fun it x -> match x with 0 -> raise ZeroFound | _ -> x * it) 1 l with ZeroFound -> 0;;
schemeでもできるか調べてみた。
srfi-34のguardを使うといいみたい。
(define (product l) (guard (con (else con)) (fold (lambda (x it) (if (zero? x) (raise 0) (* x it))) 1 l))) (product '(1 2 0 3 2)) ;=> 0
raiseは一応どんなものでも渡せるみたいだけれど、普通はコンディションオブジェクトを渡すみたい。
自分で新しいコンディション*1を定義したい場合は、define-condition-typeを使う。
(define-condition-type <zero-found> <condition> #f) (define (product l) (guard (con ((<zero-found> con) 0)) (fold (lambda (x it) (if (zero? x) (raise (condition (<zero-found>))) (* x it))) 1 l)))
参考
*1:例外のことをコンディションっていうみたい