SML# - Resources/ProgrammingExamples/Variants Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

時折,「SML#は,OCamlで提案された多相型バリアントはサポートしないのか?」
との質問をうけることがあります.

この点に関して,まず誤解を解いておきましょう.
多相型バリアントのML系言語への導入のための型理論とそのコンパイル理論は,
論文
[["A polymorphic record calculus and its compilation. ACM TOPLAS, 17(6):844-895"(a preliminary version appeard in POPL'92)|http://www.pllab.riec.tohoku.ac.jp/~ohori/research/list.html#recordcalc]]
で提案されたものであり,その起源はSML#(の前身)にあります.

この論文で示されているように,多相型バリアントの導入のための技術的問題は解決されています.
それら理論や技術は,我々が開発し,SML#の基礎をなすものですから,当然SML#に導入可能です.
しかし,我々は,主に以下の2つの理由により,SML#に多相型バリアントを導入しませんでした.
# その導入により言語の文法が複雑となり,the Definition of Standard MLで定義された言語との上位互換性を保つことが困難である判断されること.さらに,
# 多相型バリアントの主な機能はレコード多相性を用いて表現可能であること.

第一の理由は明らかと思います.
実用言語の場合,広く普及している言語の定義との上位互換性を保つことは,多少の構文上の柔軟性より重要と考えました.

第2の点を簡単に説明しましょう.
説明のために,バリアントデータとその型を
<Age = 21> : <Age:int>
のように書くことにします.
レコードによるバリアント表現の基本は,
そのデータを処理する関数を引数と
する高階の関数として表現することです.
型システムが,その関数の多相性を正確に表現できれば,
多相型バリアントも自然に表現できます.
この考え方は,関数プログラミングのデータ表現でよく現れるものです.
この考え方に従えば,<Age = 21>は,以下の関数で表現できます.
fn M => #Age M 21
この関数は,種々のバリアントを処理するメソッドスイート Mを引数として
受け取り,そのなかから"Age"用のメッソドをディスパッチします.
SML#コンパイラは,このコードに対して以下の型を推論します.
['a#{Age:int -> 'b},'b.'a -> 'b]
この型は,この関数が,"int -> 'b"型の"Age"フィールドを含むメソッドレコー
ドを受け取るオブジェクトであることを示しています.
つまり,この高階の関数型は,
  ['a#<Age:int>.'a]
のような多相型バリアント型の表現と見なすことができます.

この考え方にしたがって書かれた
* [[簡単な例|VariantSource]],および
* [[SML#での実行結果|VaraintResult]]
をご参照ください.