SML#でオーバーローディング!
SMLでは、型システムがオーバーロードをうまく扱えないため、基本的にオーバーロード不可能なのですが、
トップレベルに公開されている一部の数値演算(関数)は特別扱いで、オーバーロードされています。(OCamlではこの特別扱いを撤廃してるのが特徴的です。)
これがあると、数値同士の足し算やかけ算が書きやすくなります。
- 5.0 + 6.2; val it = 11.2 : real - 100 + 256; val it = 356 : int
SML#ではこれをユーザランドで定義出来るらしいと風の噂を聞きつけたので
さっそく使ってみました。
(* to_string.smi *) _require "basis.smi" val to_str = case 'a in 'a -> string of int => Int.toString | real => Real.toString | word => Word.toString (* ここで関数定義は書けないみたい *) (* to_string.sml *) (* からっぽ *)
smiに書く必要があるみたいです。なのでその場でラムダ式とか書けません。
別モジュールのインターフェースとして見えているシンボルに振り分けるだけ…といった感じでしょうか。
呼び出す側
(* main.smi *) _require "basis.smi" _require "to_string.smi" (* main.sml *) val _ = app print [to_str 314, "\n", to_str 1.24, "\n", to_str 0x15, "\n"];
オーバーロードされた文字列化関数が定義出来ました!!
実行します
~/work/smlsharp $ smlsharp.exe -c to_string.sml ~/work/smlsharp $ smlsharp.exe main.sml ~/work/smlsharp $ ./a.out 314 1.24 21
ちゃんと型に応じて適切な関数が呼ばれていますね!
ホントはこんな感じに書けるといいんですが…。どこまで出来るんだろうか。
fun g_to_str x = case x of NONE => "NONE" | SOME v => g_to_str v