1 2 3 4 5 6 7 8 9 10 | #light let (||-||) x y = printfn "%A join %A: 1 vs 1" let (>|-||) x y = printfn "%A join %A: 1..* vs 1" let (>@-||) x y = printfn "%A join %A: 0..* vs 1" let (|@-||) x y = printfn "%A join %A: 0..1 vs 1" |
F# ではオペレータの再定義が自由なので、色々な演算子が作れる…ってことは、ER図の鳥足みたいのもできるのでは?と思ったのがこれ。
演算子としては異様、と言いますか単純に外部結合をするだけのために使う、のかな。
1 | Products.category_id >@-@| Categories.id |
のような感じで、Products テーブルと Categories テーブルが「多対1」のように示すわけですが、思いついてはみたけれど何のために使うのかわかりません。O/R マッピングを XML ファイルで定義するよりも使い手があれば、それでもいいんですが。
そういえば、xml 形式の定義で思い出したのですが、設定ファイルというのは何も xml 形式やバイナリ形式にする必要もないのです。設定ファイルというと、昔は ini ファイル形式だったり、適当なバイナリ形式だったり、テキスト形式だったりして、最近は xml 形式が流行りな訳ですが、コード自身をファイルに保存しておくという形式があります。
TeX 形式や postscript 形式がそうで、実はコードとデータを兼ねた形式になります。あと、LISP もコードとデータを混在させることが可能です。
と言葉で書いても良くわからないので、具体例を出してみます。
1 2 3 4 5 6 7 | < persons > < person > < name >masuda tomoaki</ name > < addr >tokyo</ addr > < telephone >03-0000-0000</ telephone > </ person > </ persons > |
このような XML 形式があるとします。これを INI ファイル形式で書くとすると、一例としてこんな風に書けます。
1 2 3 4 5 | [persons] name="masuda" [person.masuda] addr="tokyo" telephone="03-000-0000" |
あと LISP で書くとこんな感じです。
1 2 3 4 5 | (persons (person (name "masuda" ) (addr "tokyo" ) (telehphone "03-0000-0000" ))) |
# 本当はクォートしないといけないような気がするのですが、まあ、こんな感じです。
実は、XML 形式と LISP 形式はトポロジー的に似ています。閉じ括弧/タグが必要という点で同じですね。
今度は TeX 風に書いてみると、
1 2 3 4 5 6 7 | \begin{persons} \begin{person} \set name="masuda" \set addr="tokyo" \set telephone \end{person} \end{persons} |
な感じです。\set のような書き方があったハズですが、覚えていません。
さて、肝心の C++ のコード自体でデータ構造を表そうとすると次のように書けます。
1 2 3 4 5 | Persons.Add( new Person( new Name( "masuda" ), new Addr( "Tokyo" ), new Telephone( "03-0000-0000" ))); |
XML 形式や LISP 形式に似ています。これならば、XML 形式にしたほう楽だろうと思うかもしれませんが(いや、それは事実なんですけど)、このように C++ のコードにしておくと、コードの中にデータを埋め込めるという利点があります。
このデータ構造を data.txt というファイルに記述しておき include します。
1 2 3 4 5 6 | void func() { #include "data.txt"; // Persons に対して操作をする } |
こんな風にすると、データの差し替えが手軽にできます。今で云えば、JSON の埋め込み型の要領です。
実はこの技、データだけを他の処理系(Excelなど)から生成して、C++ で取り込むということができます。C# や VB だとこれが使えないんですよね…ちょっと不便かなぁと。