続 lazy pattern
Michel 自身も caml-devel でコメントしているが、lazy _ というパターンは内部を見る必要がないにもかかわらず、force する:
(fun (lazy _) -> ()) (lazy (prerr_endline "hello"))
は hello を出力する。まあ、これはいいんじゃないかと思う。lazy とパターン中で明示されているから、forceするのが自然だろう。
lazy value がパターン中で force されるタイミングが微妙で、pattern match のコンパイルを体感できる:
let f = function | (lazy true, lazy v) -> prerr_endline v | _ -> prerr_endline "silence" ;; let g = function | (lazy v, lazy true) -> prerr_endline v | _ -> prerr_endline "silence" ;; let _ = f (lazy true, lazy (prerr_endline "hello"; "world"));; let _ = f (lazy false, lazy (prerr_endline "hello"; "world"));; let _ = g (lazy (prerr_endline "bonjour"; "le monde"), lazy true);; let _ = g (lazy (prerr_endline "bonjour"; "le monde"), lazy false);;
tuple の左から pattern match しているのがわかる。tuple の evaluation order と逆であるのがちょっと面白い:
# (prerr_endline "hello", prerr_endline "world");; world hello
まあ、OCamlはこの手の重箱の隅をつつくような仕様は適当、というおおらかなスタンスの言語であるので、上のような妙な lazy pattern は書かない、という事に尽きる事になるだろう。