osiire’s blog

ふしぎなそふとやさん

GoF in OCaml for Advent Calendar 2012 #1

年末で忙しいのにやってしまった感があります。OCaml Advent Calendar作ってしまいました。
 OCaml Advent Calendar
作ったからには三日坊主は目指して参ります。参加したい方は上のページで参加表明お願いします。編集権限お渡しします。

問題のネタですが正直考えるのが大変です。そこで、私の勉強がてら、所謂GoFデザインパターンOCamlで書いて紹介してみることにします。これなら20個くらい機械的にいけるでしょう。ただ、私はデザインパターンについて詳しくないので、設計ガーとかオブジェクト指向的にワーとか知りません。とりあえず表面的な書き換えだけ目指します。
なお、GoFOCamlでっていうネタは下記の論文にあります。日めくりなんてかったるい人はどうぞ。なお、この論文ではGoFパターンをOCamlのオブジェクト機能を使って再現しています。対して本エントリーではモジュールを主に使っていこうと思います。省力化という意味もありますし、うちの会社ではJavascriptを生成するとかの目的以外ではオブジェクト中心のコードは書かないので、モジュールのテクニックをまとめておきたいからです。
 http://people.csail.mit.edu/dnj/teaching/6898/projects/vicente-wagner.pdf
あと、昔yoriyukiさんも同じ事やってらっしゃいます。さすがに内容素晴らしいのですが、数が少ないようなので私は数で攻めます(いや、あくまで希望的観測)。

さて、最初のパターンは何にしよう。とりえあず構造系からいきましょう。Adapterパターンです。Adapterパターンは既存のクラスをラップして自分たちが使いやすいようにメソッド名や引数を変更しちゃおうというものですね。
 http://ja.wikipedia.org/wiki/Adapter_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3
上のwikipediaの例をOCaml化してみます。

(* 既存の商品モジュール. *)
module Product = struct 
  type t = { cost : int }
  let getCost p = p.cost
end

(* getCostをgetPriceに変更したい. *)
(* 継承によるアダプター *)
module ProductAdapter = struct
  include Product
  let getPrice p = getCost p
end

(* 委譲によるアダプター *)
module ProductAdapter = struct
  type t = Product.t
  let getPrice p = Product.getCost p
end

こんなんでいいのかしら?比較的そのまま適用できますね。
次回に続く!-> http://d.hatena.ne.jp/osiire/20121202