";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))
引用されていないバージョン:codinggroundで試してください。
引用バージョン:codinggroundで試してください。
出力は次のようになります。
> val it = "{some string}" : string
> val it = "{some string}" : string
{output to stdout}> val it = fn : string -> unit
コードは宣言ごとに解釈され(それぞれ;
が宣言を終了する)、各宣言の値と型を表示するためです。
バックグラウンド
SMLには、次の形式のクインがあります<code>"<code in quotes>"
。
str(chr 34);(fn x=>print(x^it^x^it))"str(chr 34);(fn x=>print(x^it^x^it))"
そして、フォーム内の1つ"<code in quotes>"<code>
:
";str(chr 34)^it;print(it^it)";str(chr 34)^it;print(it^it)
どちらも、<code>
-partに引用符が含まれていないため、何もエスケープする必要なく引用できるため、クイン"
を出力するために必要なのはによって与えられstr(chr 34)
ます。
またit
、宣言で明示的な識別子が指定されていない場合に使用される暗黙的な識別子に大きく依存しています。
最初クワインでstr(chr 34);
バインドit
含む文字列に"
、fn x=>
一つの引数を取る無名関数を開始しx
、その後、連結x^it^x^it
し、得られた文字列を出力します。この匿名関数は、プログラムコードを含む文字列に直接適用されるため、連結によってがx^it^x^it
得られ<code>"<code>"
ます。
2番目のクインは、に";str(chr 34)^it;print(it^it)";
バインドされた文字列としてのプログラムコードだけで始まりit
ます。次にstr(chr 34)^it;
、引用符を文字列の先頭に連結します。明示的な識別子が指定されていないため、結果の文字列"<code>
はにバインドされit
ます。最後にprint(it^it)
、文字列とそれ自体を連結し、出力します"<code>"<code>
。
説明
編集: 108バイトバージョンでは最新ではありませんが、この説明を読んだ後でも理解できるかもしれません。
クォートセーフクインは、上記のアプローチの両方を組み合わせており、それ自体が形式"<code>"<code>
です。これを再度引用符で囲むとyields ""<code>"<code>"
になるので、空の文字列を取得し、次に他の形式のクインを取得します。
つまり、プログラムは"<code>
識別子によってフォーム内の独自のソースを与えられるかit
、またはit
単に引数として"
独自のソース<code>
を与えられるため、そのような引数を処理する関数でなければなりません。
(if size it>1then(print(it^it);fn _=>())else fn x=>print(it^it^x^it^x^it))
我々は、その場合に識別するために、我々は、の大きさかどうかをチェックit
次いで1より大きい場合ではないit
で"
、我々は、第二の場合であるので、else
-part戻る匿名関数fn x=>print(it^it^x^it^x^it)
の文字列としてソースが続くので、次に呼び出され。it^it^
プログラムの開始時に空の文字列に必要な先頭に注意してください。
size it
が1より大きい場合、then
-partにあり、実行するだけprint(it^it)
ですよね?ない非常に、私はSMLが強く型付けされたことを伝えることを怠っているためその条件ということを意味if <cond> then <exp_1> else <exp_2>
する必要があります常に再び表現することを意味し、同じタイプの持ち<exp_1>
と<exp_2>
必要性は同じ型を持つことを。else
パーツのタイプはすでにわかっています。文字列を受け取って呼び出す匿名関数print
はtype string -> <return type of print>
をprint
持ち、type を持っていますstring -> unit
(他の言語unit
と似てvoid
いる)ため、結果の型は再びstring -> unit
です。
したがって、then
パーツがprint(it^it)
type のみである場合、unit
タイプ不一致エラーが発生します。じゃあどうfn _=>print(it^it)
?(_
自分自身でこの無名関数は種類がある使用されていない引数のワイルドカードである)ので、強制私たちの条件付きのコンテキストで、任意のタイプの略で、これはうまくいくタイプ。(type変数はtypeでインスタンス化されます。)ただし、この場合、匿名関数は呼び出されないため、何も出力しません!-part に進むと、コード全体がであるため、-partは関数に評価されますが、その後に何も来ないため、呼び出されません。'a -> unit
'a
string -> unit
'a
string
then
"<code>"<code>
<code>
代わりに、我々は、フォーム有するsequentialisation使用する任意のタイプおよび種類を有することができる全体sequentialisationの種類を提供します。機能的な観点から、to の値は単純に破棄されますが、SMLは命令型の構造もサポートするため、式に副作用が生じる可能性があります。つまり、-part として、最初に印刷してから正しい型の関数を返します。(<exp_1>; ...; <exp_n>)
<exp_1>
<exp_n-1>
<exp_n>
<exp_1>
<exp_n-1>
(print(it^it);print)
then
print