Lazyの合成

Lazyのアクティブパターンを使うとすっきり書けることに気づきました。

(* ('a -> 'b -> 'c) -> Lazy<'a> -> Lazy<'b> -> Lazy<'c> *)
let lift2 f x y = lazy (
  let (Lazy a) = x
  let (Lazy b) = y
  f a b)

do
  let x = lazy (10 + 20)
  let y = lazy (1 + 2)
  let z = lift2 (+) x y
  printfn "%A" (z.Value) (* 33 *)

コンピュテーション式じゃないけど次のようなコンピュテーション式に見えなくもない。

let lift2 f x y = lazy {
  let! a = x
  let! b = y
  return f a b}

こういう感じのアクティブパターンの使い方は、ほかでも便利なことあるかも。