Scala School/Basics 学習メモ


はじめに

おそらくネット上にあるもっとも優れたScala教材の一つであろうScala Schoolについて、
気になったことや試したことなどを部分的に忘備録としてメモしておこうと思います。
Scala Schoolは説明が非常にさっぱりしているのでその補足になればいいかなと思います。
Lessonsごとに記事は分けます。まずは最初のlessonであるbasicsから。

本編

Anonymous function

リスト1
val a = (x:Int) => x + 1
a(5) //結果は6

val b = (x:Int,y:Int) => x + y //複数の引数ももちろんOK
c(5,6) //結果は11

val c = (x:Int)(y:Int) => x + y //NG.匿名関数でcurriedの形はできない

val d = (x:Int) => (y:Int) => x + y //どうしても匿名でcurriedの形で書きたい場合はこうする
d(3)(7) //結果は10

scalaではパターンcの書き方をcurried functionとしていますが、本来的にはdの書き方のほうがクロージャを利用した正統なcurried functionなのかもしれません。
匿名でないcurried functionについては後述。

Partial applicaiton

リスト2
def adder(m:Int,n:Int) = m + n //まず定義

val addTwo = adder(2, _:Int) //1.これで部分適用できる
val addTwo = adder(2, _)     //2.型指定を省略してもOK
val addTwo = adder(_, 2)     //3.最後の引数だけでなくどの引数でもワイルドカードにできる

※便宜的にaddTwoという同じ名前を複数回つかっています。valなので実際にはエラーとなります。

Curried functions

リスト3
def multiply(m:Int)(n:Int) = m * n //関数を定義

val timesTwo = multiply(2) _      //4.OK
val timesTwo = multiply(2)(_)     //5.OK
val timesTwo = multiply _(2)      //6.エラー
val timewTwo = multiply(_)(2)     //7.これもエラー
val timesTwo = multiply(_:Int)(2) //8.型指定を入れればOK

※便宜的にtimesTwoという同じ名前を複数回(以下略

パターン7はmissing parameter typeというエラーになりますが理由がよくわかりません。
stackoverflowで聞いてみてはいますが、まだ回答なし。(わかる方いたらお願いします)
scalaのバージョンによってはパターン2.や3.も同様のエラーになります。

Variable length arguments

リスト4
def capitalizeAll(args: String*) = {
  args.map { arg =>
    arg.capitalize
  }
}

個人的に少しひっかかったこのコード。実は引数は{}でも入力することができるようです。
実際

println{"asdf"}

これでも動きます。
式そのものも、オブジェクト・値としてあつかうのでこのようになっているのかもしれませんね。javaの習性であれ?と思いました。

このあとscala school/basicsではクラスやトレイトの説明に入りますが、そのへんは特別気になるところもなかったので省略します。
(あとからなにか思い返して追加するかもしれませんが)