osiire’s blog

ふしぎなそふとやさん

Dvarの基本ができた

concurrent cellに新しいモジュールDvar(http://forge.ocamlcore.org/plugins/scmsvn/viewcvs.php/trunk/dvar.ml?rev=20&root=ccell&view=markup)を導入しました。で、その基本的な関数がやっとできた。最近これを作ってたので、籠ってました。
Dvarとはどんなものかというと、Mvarの一種で、変数同士の依存関係を把握してくれて、ある変数の値が更新されると依存関係のある変数を全部適切にアップデートしてくれるという便利なやつです。要するに、Functional Reactive Programmingに似たシステムですね。シグネチャーはこれ。

module Dvar : sig
  type 'a t
  val make : 'a -> 'a t * ('a -> unit Event.event)
  val async_make : 'a * 'a Mbox.t -> 'a t
  val depend : 'a t -> ('a -> 'b) -> 'b t
  val dyn_depend : 'a t -> ('a -> 'b) t -> 'b t
  val read : 'a t -> 'a Event.event
end

makeが返すのはDvar.t型の箱とそのDvar.t型の箱に新しい値をセットする関数。async_makeは、引数のMbox.t型の箱に値を入れると、それを新しい値だと認識してくれるDvar.t型の箱を生成する関数。
とりあえず、使ってみるとこんな感じですわ。

# open Ccell;;
# open Event;;
# let a, setter = Dvar.make 1;;
val a : int Ccell.Dvar.t = <abstr>
val setter : int -> unit Ccell.Event.event = <fun>
# let b = Dvar.depend a (fun x -> x + 1);;
val b : int Ccell.Dvar.t = <abstr>
# sync (setter 2);;
- : unit = ()
# sync (Dvar.read b);;
- : int = 3
  1. まず1という値のaを用意。
  2. aに1を加えたものがbであるという依存関係を持つbを生成。
  3. aに2を代入。
  4. bの値を読み取ると、3になっている。

これが一番基本的な使い方。
Mbox.tを利用すると、非同期なイベントによって変化する依存関係も記述できる訳です。
さー、これを使ってamthingをグレードアップさせるぞー。