続 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 は書かない、という事に尽きる事になるだろう。