#文字列補完
C# 6.0から,文字列補完機能が追加されました.String.Formatと同じようなことを簡単に書けるようになりました.
int i = 10;
Console.WriteLine($"i={i}"); // "i=10"という文字列になる.
Console.WriteLine(String.Format("i={0}", i); //上と同じ.
Nemerleは昔から存在しています.
def i : int = 10;
WriteLine($"i=${i}"); // "i=10"という文字列になる.
WriteLine($"i=$i"); // 後ろの文字がスペース,又は,終端だった場合,括弧を省略することができる.
WriteLine($"i=${i / 2}"); // こんなことも可能
#繰り返し処理(for,while,再帰関数)
Nemerleの繰り返し処理方法は4つあります.が,そのうちの一つの方法である,Foreachはリストのところで紹介します.
それぞれの例は,同じ処理をします.
##for
C#と同じです.
for(mutable n = 0; n < 10; ++n) {
WriteLine($"n is $n");
}
##while
C#と同じです.
mutable n = 0;
while(n < 10) {
WriteLine($"n is $n");
++n;
}
##do-while
C#と同じです.
mutable n = 0;
do {
WriteLine($"n is $n");
++n;
} while(n < 1);
##repeat
repeat (n : long) {
code
}
n(整数型)の回数だけcodeをリピートします.
##再帰関数
関数型でお馴染みの再帰関数です.慣れるには時間がかかりますが,コツは,必要な条件と必要な変数を引数にすることだと思います.
loopfunc(n : int) : void {
WriteLine($"n is $n");
when(n < 10) loopfunc(n + 1);
}
main() : void {
loopfunc(0);
}
Nemerleでは自由に繰り返し処理方法を選択できますし,マクロで,拡張することもできます.
#_
関数型言語では多くの人にとってお馴染みな,”_”がNemerleでも使うことができます.
###戻り値の破棄
Nemerleでは,戻り値ありの関数を戻り値なしの関数のように使うことはできません.
WriteLine("hogehoge"); // OK
ReadLine(); // Compiler Error!
_ = ReadLine(); // OK
_に代入することによって,戻り値を破棄する必要があります.
###引数の破棄
引数に,_を使うことにより,どんな値が代入されても,破棄することができます(型は一定).Overrideな関数などに便利です.
Add(a : int, b : int, _ : int) : int {
a + b;
}
#高階関数&ラムダ式(匿名関数)
関数型言語ではおなじみ,C#でもLINQ等によって馴染み深くなってきた高階関数とラムダ式(匿名関数をつくる式のこと)です.
C#のラムダがわかることを前提とします.
まず,匿名関数の型の書き方は,
paramator_type -> return_type
です.ラムダ式の書き方は,
fun(paramator) { code }
です.具体例を挙げなければわかりませんね.
Func<int,long> intTolong = (n) => (long)n;
Func<int,int,long> Add = (n, m) => (long)(n + m);
mutable intTolong : int -> long = fun(n) {n :> long;};
mutable Add : int * int -> long = fun(n, m) {(n + m) :> long;};
//型推論も効きます
mutable intTolong = fun(n) {n :> long;};
mutable Add = fun(n, m) {(n + m) :> long;};
//C#ライクな書き方もできます(Nemerle.Core.=>)
mutable intTolong = (n) => n :> long;
2つの変数は同じ処理をします.丁寧に書くと,こんな感じです.(型推論がきちんとされるので,型を明示的になくてもおk)
引数が2つ以上ある場合は,int * intのように,*を間にはさみます.
ちなみに,この場合,下のように短く書くことができます.
def intTolong(n) {n :> long;};
def Add(n, m) {(n + m) :> long;};
Nemerleの匿名関数はC#と同じで,静的スコープであるため,匿名関数外で定義された変数を参照・変更することができます.
main() : void {
mutable n = 12
def WriteAndDouble() {
WriteLine(n);
n *= 2;
}
WriteAndDouble();
WriteAndDouble();
}
出力結果
12
24
では,実際に高階関数を作ってみます.
DoTwice(fnc : void -> void) : void {
fnc();
fnc();
}
Main() : void {
DoTwice(fun() {WriteLine("Nemerle!");});
}
戻り値・引数がない場合は,voidを使います.
2回"Nemerle"
が出てくれば,成功です.
#〆
次回からもどんどん関数型の道を進みます.
入門Ⅲへ