19. 省略
val list = Seq(1, 2, 3, 4, 5)
list map { i =>
i + 1
}
わかる
!!?
◎ 知ってないと読めない形が多い、、
◎ 容赦なくライブラリのチュートリアル等で出
て、DSLと見分けつかなくて困った
◎ 頻出の形をPickupして紹介します。
○ あとは出てきたときに頑張る
“Scala の省略ルール早覚え
“Scalaでのメソッド呼び出しの書き方一覧と推奨される書き方
20. 省略: ラムダ式
val list = Seq(1, 2, 3, 4, 5)
def double(i: Int): Int = {
i * 2
}
list.map(double)
val double:(Int) => Int = (i: Int) => i * 2
list.map(double)
○ doubleは普通の関数定義。mapは引数1つの関数を引数に
取る高階関数。
関数型定義
のS.S.
Function1のインスタンス
=無名関数=ラムダ式
○ 関数定義の省略。Function1型の変数として書ける。右辺
はラムダ式と呼ばれる
21. 省略: 中置記法
val list = Seq(1, 2, 3, 4, 5)
val double2:(Int) => Int = (i: Int) => i * 2
list.map(i => i * 2)
list map { i =>
i * 2
}
○ 引数の型が自明の場合、引数型を省略してよい
○ 引数が1つの場合、()を省略して良い
: Int と () を省略
list map {_ * 2}
○ . と () の省略(中置記法)
○ 関数を引数に1つ取る場合、() の代わりに {} を使って良い
この形が頻出!
○ すべての引数が1回しか使われない場合、引数定義を省略
して `_` にできる(!)
_ は一つ目の引数、の意。頻出!!
22. ライブラリに見る中置記法
val name = "martin.lover"
val memberId: Option[Long] = DB readOnly { implicit session =>
sql"select id from members where name = ${name}"
.map(rs => rs.long("id"))
.single
.apply()
}
scalikeJDBC
"Specs2" should {
"use infix notation" in {
"test" mustEqual "test"
}
}
specs2
val route: Route =
get {
pathPrefix("item" / LongNumber) { id =>
// there might be no item for a given id
val maybeItem: Future[Option[Item]] = fetchItem(id)
akka-http
should, inが高階関数
() => Flagment
readOnly が高階関数
DBSession => A
pathPrefixが高階関数
Directive1
24. For Comprehension
val maybeName: Option[String] = Some("martin.lover")
val maybeAge: Option[Int] = Some(33)
case class Person(name:String, age:Int)
val person: Option[Person] =
for {
name <- maybeName
age <- maybeAge
} yield Person(name, age)
わかる
!!?
◎ 覚えるとすごい便利&強力
◎ 制御を追わなくて良くなるので、可読性↑↑
○ 好みはあると思います。。LODEOでは頻出。
わかる
“ Scalaスケーラブルプログラミング(コップ本)
23章 for式の再説
25. For Comprehension: 展開
val maybeName: Option[String] = Some("martin.lover")
val maybeAge: Option[Int] = Some(33)
val person: Option[Person] =
for {
name <- maybeName
age <- maybeAge
} yield Person(name, age)
val person: Option[Person] =
maybeName flatMap { name =>
maybeAge map { age =>
Person(name, age)
}
}
○ `<-` はジェネレーターと呼ばれる
○ flatMap とか map とか foreach とか withFilter に展開される
なるほど
わからん
26. For Comprehension: 覚え方
val person: Option[Person] =
for {
name <- maybeName
age <- maybeAge
addr <- maybeAddr
} yield Person(name, age)
Forを始めた外側の
型が最後まで続く
Option[String]外側剥がれる
name:String
外側の型を
揃える
Option[T]
中はなんでも良い
計算失敗したら
それ以上実行
しない
最後まで成功したら
外側の型でくるんで返す
○ flatMap, mapが実装されていれば、ここでいう「外側の型」
として使える=「文脈付きの型」
○ 上の例なら、maybeName,maybeAge,maybeAddrがすべて
Someなら Some(Person), どれかNoneならNoneが返る
27. For Comp~: うれしいこと
maybeName match {
case Some(name) => maybeAge match {
case Some(age) => maybeAddr match {
case Some(addr) => Person(name, age)
case None => None
}
case None => None
}
case None => None
}
(maybeName, maybeAge, maybeAddr) match {
case (Some(name), Some(age), Some(addr)) =>
Some(Person(name, age))
case _ => None
}
○ こういうコードが見やすく改善できる
○ matchのネストを見たらfor文で書き換えるプルリクチャンス!
どこで終わるの、、、
()多すぎ、、