LoginSignup
0
1

More than 5 years have passed since last update.

多相バリアントによる多相レコードの表現

Last updated at Posted at 2015-03-08

多相バリアントについて

多相バリアントについては,

あたりを読むとよいでしょう.(この記事では解説しません).

多相レコードについて

多相レコードについては,

を読むとよいでしょう.

多相レコードによる多相バリアントの表現について

多相レコードによる多相バリアントの表現については,

などに,詳しく書かれております.

多相レコードで多相バリアントができるなら,多相バリアントで多相レコードもできるはず!
と,考えまして, OCaml の多相バリアントで多相レコードが実装できないか試しました.

多相バリアントで多相レコード

結論としてはこうなります.

let id x = x
let pair x y = function `Fst f -> f x | `Snd f -> f y
let fst p = p (`Fst id)
let snd p = p (`Snd id)

let triple x y z = function `Fst f -> f x | `Snd f -> f y | `Third f -> f z
let third p = p (`Third id)

(* fst は pair/triple のどちらに対しても使える *)
let i = fst (pair 1 'a')
let j = fst (triple 2 'b' 3.14)

注意(追記)

OCaml には (Relaxed) Value Restriction があるので,ちゃんと使うには η expansion
する必要があります.

let id x = x
let pair x y = function `Fst f -> f x | `Snd f -> f y
let fst p = p (`Fst id)
let snd p = p (`Snd id)

let triple x y z = function `Fst f -> f x | `Snd f -> f y | `Third f -> f z
let third p = p (`Third id)

let p = fun x -> pair 1 'a' x
let i = fst p
let j = snd p

蛇足なこと

最初,ADTをオブジェクト指向言語におけるメッセージだと捉えて,次のような構造を考えました.

let pair x y = function `Fst -> x | `Snd -> y
let fst p = p `Fst
let snd p = p `Snd

let triple x y z = function `Fst -> x | `Snd -> y | `Third -> z
let third p = p `Third

(* fst は pair/triple のどちらに対しても使える *)
let i = fst (pair 1 2)
let j = fst (triple 2 3 4)

しかし,これだと, pair x y の x と y が同じ型でないといけないことになってしまいます.

let pair x y = function `Fst -> x | `Snd -> y
let fst p = p `Fst
let snd p = p `Snd

let triple x y z = function `Fst -> x | `Snd -> y | `Third -> z
let third p = p `Third

(* こういうペアはつくれない *)
let p = pair 1 'b'

そこで関数をひとつ噛ませるという工夫をしました.
ペアの定義は

let pair x y = function `Fst f -> f x | `Snd f -> f y
let fst p = p (`Fst id)
let snd p = p (`Snd id)

こうすることで,ペアのそれぞれが異なる型でもうまく動くようになりましたとさ.

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1