1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Nemerle入門Ⅱ ~便利な機能,ループ,関数型言語の世界への第一歩~

Last updated at Posted at 2016-02-21

#文字列補完
C# 6.0から,文字列補完機能が追加されました.String.Formatと同じようなことを簡単に書けるようになりました.

string
int i = 10;
Console.WriteLine($"i={i}"); // "i=10"という文字列になる.
Console.WriteLine(String.Format("i={0}", i); //上と同じ.

Nemerleは昔から存在しています.

string
def i : int = 10;
WriteLine($"i=${i}"); // "i=10"という文字列になる.
WriteLine($"i=$i"); // 後ろの文字がスペース,又は,終端だった場合,括弧を省略することができる.
WriteLine($"i=${i / 2}"); // こんなことも可能

#繰り返し処理(for,while,再帰関数)
Nemerleの繰り返し処理方法は4つあります.が,そのうちの一つの方法である,Foreachはリストのところで紹介します.
それぞれの例は,同じ処理をします.
##for
C#と同じです.

for
for(mutable n = 0; n < 10; ++n) {
  WriteLine($"n is $n");
}

##while
C#と同じです.

while
mutable n = 0;
while(n < 10) {
  WriteLine($"n is $n");
  ++n;
}

##do-while
C#と同じです.

while
mutable n = 0;
do {
  WriteLine($"n is $n");
  ++n;
} while(n < 1);

##repeat

repeat
repeat (n : long) {
code
}

n(整数型)の回数だけcodeをリピートします.

##再帰関数
関数型でお馴染みの再帰関数です.慣れるには時間がかかりますが,コツは,必要な条件と必要な変数を引数にすることだと思います.

rec_func
loopfunc(n : int) : void {
  WriteLine($"n is $n");
  when(n < 10) loopfunc(n + 1);
}

main() : void {
  loopfunc(0);
}

Nemerleでは自由に繰り返し処理方法を選択できますし,マクロで,拡張することもできます.
#_
関数型言語では多くの人にとってお馴染みな,”_”がNemerleでも使うことができます.
###戻り値の破棄
Nemerleでは,戻り値ありの関数を戻り値なしの関数のように使うことはできません.

return__
WriteLine("hogehoge"); // OK
ReadLine(); // Compiler Error!
_ = ReadLine(); // OK

_に代入することによって,戻り値を破棄する必要があります.
###引数の破棄
引数に,_を使うことにより,どんな値が代入されても,破棄することができます(型は一定).Overrideな関数などに便利です.

param__
Add(a : int, b : int, _ : int) : int {
  a + b;
}

#高階関数&ラムダ式(匿名関数)
関数型言語ではおなじみ,C#でもLINQ等によって馴染み深くなってきた高階関数とラムダ式(匿名関数をつくる式のこと)です.
C#のラムダがわかることを前提とします.
まず,匿名関数の型の書き方は,

paramator_type -> return_type

です.ラムダ式の書き方は,

fun(paramator) { code }

です.具体例を挙げなければわかりませんね.

lambda
Func<int,long> intTolong = (n) => (long)n;
Func<int,int,long> Add = (n, m) => (long)(n + m);
lambda
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のように,*を間にはさみます.
ちなみに,この場合,下のように短く書くことができます.

lambda_short
def intTolong(n) {n :> long;};
def Add(n, m) {(n + m) :> long;};

Nemerleの匿名関数はC#と同じで,静的スコープであるため,匿名関数外で定義された変数を参照・変更することができます.

lexical_scoping
main() : void {
  mutable n = 12
  def WriteAndDouble() {
    WriteLine(n);
    n *= 2;
  }
  WriteAndDouble();
  WriteAndDouble();
}

出力結果

12
24

では,実際に高階関数を作ってみます.

rich_function
DoTwice(fnc : void -> void) : void {
  fnc();
  fnc();
}

Main() : void {
  DoTwice(fun() {WriteLine("Nemerle!");});
}

戻り値・引数がない場合は,voidを使います.
2回"Nemerle"が出てくれば,成功です.

#〆
次回からもどんどん関数型の道を進みます.

入門Ⅲ

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?