OCamlテクニック/ghost

OCamlで幽霊型を応用してみました。 お金型に税込みかどうかの区別を付けて、二重に税金を計算することを 防ぐことができます。

まずシグネチャーを定義します。 ここでは、裸の金額と税込みの金額を区別した型を定義して、 tax関数は裸の金額にしか適用できないよう制限します。

# module type MoneySig = sig
    type 'a money constraint 'a = [< `Naked | `Taxed ]
    val make : float -> [`Naked] money
    val add : 'a money -> 'a money -> 'a money
    val mul : 'a money -> 'a money -> 'a money
    val tax : [`Naked] money -> [`Taxed] money
    val show : 'a money -> string
  end
  ;;
module type MoneySig =
  sig
    type 'a money constraint 'a = [< `Naked | `Taxed ]
    val make : float -> [ `Naked ] money
    val add : ([< `Naked | `Taxed ] as 'a) money -> 'a money -> 'a money
    val mul : ([< `Naked | `Taxed ] as 'a) money -> 'a money -> 'a money
    val tax : [ `Naked ] money -> [ `Taxed ] money
    val show : [< `Naked | `Taxed ] money -> string
  end

先ほどのシグネチャーを適用したモジュールを作ります。 実体をfloatとしています。

# module Money : MoneySig = struct
    type 'a money = float constraint 'a = [< `Naked | `Taxed ]
    let make x = x
    let add = (+.)
    let mul = ( *.)
    let tax x = x *. 1.05
    let show = string_of_float
  end;;
module Money : MoneySig

では、Moneyモジュールを使ってみましょう。

# let juice = Money.make 120.0;; 
val juice : [ `Naked ] Money.money = <abstr>

ジュースは120円、税抜きとします

# Money.tax (Money.tax juice);;  
This expression has type [ `Taxed ] Money.money but is here used with type
  [ `Naked ] Money.money
These two variant types have no intersection

二重に課税すると型エラーです。

# Money.add juice juice;;
- : [ `Naked ] Money.money = <abstr>
# let pay = Money.tax juice;;
val pay : [ `Taxed ] Money.money = <abstr>
# print_string (Money.show pay);;
126.- : unit = ()

通常の使い方はこんな感じ。

# Money.add juice pay;;
Characters 16-19:
  Money.add juice pay;;
                  ^^^
This expression has type [ `Taxed ] Money.money but is here used with type
  [ `Naked ] Money.money
These two variant types have no intersection
# 

裸の金額と税込み金額をごちゃ混ぜにして足し算しようとしても、きちんとエラーになります

  • すごいなるほど!ところでconstraintというのは予約語ですか?こういう型の構文をはじめて見るのですが -- けいご? 2006-12-22 (金) 21:09:12
  • ああ,'aが[`Naked]か[`Taxed]の場合しかないという意味ですね?. -- けいご? 2006-12-22 (金) 21:10:50
  • constraint は予約語です。意味はそのまんまですね :) 今回は多相ヴァリアントを閉じた形でconstraintにしています。 -- ogasawara? 2006-12-22 (金) 23:20:12

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-10-23 (木) 09:52:40 (4416d)