Scala IDE for Eclipseが2.0.0になってたですの。
ばーじょんあっぷしたら、インデントがズレまくる現象が治りましたの。ひゃふー
やー。。いちど崩れたインデントを治すのに、手動でスペースキーを連打するのは超大変でしたの。
ScalaIDE.orgさんありがとうですの!
「Option型=コレクション」と考えてみると、
謎なのがmapとflatMapですの。
結論から言うと、flatMapの挙動が斜め上なんですの。
コード
val list = List(List(1,2), List(1,2))
val opt = Option(list)
println(opt.flatMap(n => Option(n)))
println(opt.map(n => n))
結果
Some(List(List(1, 2), List(1, 2)))
Some(List(List(1, 2), List(1, 2)))
なんとなく、flatMapなら「Some(List(1, 2, 1, 2))」となりそうなものですけど、mapの結果と一緒なのですの。
Option型のmapとflatMapの違いはたぶん、関数の定義が微妙に違うだけなんですの。
map [B] (f: (A) ⇒ B ): Option[B]
flatMap [B] (f: (A) ⇒ Option[B]): Option[B]
Scala API(*)の説明もこんな口ぶりですの。
原文:Slightly different from map in that f is expected to return an Option (which could be None).
意訳:fがOption(Noneの可能性も有り)を返すことになっているという点でmapとわずかに異なる
その微妙な引数の差を、あえてmapとflatMapという名前で区別する意味がわかりませんの。ぷんすかぷん
*)Optionのページ (2.9.1 final)
謎なのがmapとflatMapですの。
結論から言うと、flatMapの挙動が斜め上なんですの。
コード
val list = List(List(1,2), List(1,2))
val opt = Option(list)
println(opt.flatMap(n => Option(n)))
println(opt.map(n => n))
結果
Some(List(List(1, 2), List(1, 2)))
Some(List(List(1, 2), List(1, 2)))
なんとなく、flatMapなら「Some(List(1, 2, 1, 2))」となりそうなものですけど、mapの結果と一緒なのですの。
Option型のmapとflatMapの違いはたぶん、関数の定義が微妙に違うだけなんですの。
map [B] (f: (A) ⇒ B ): Option[B]
flatMap [B] (f: (A) ⇒ Option[B]): Option[B]
Scala API(*)の説明もこんな口ぶりですの。
原文:Slightly different from map in that f is expected to return an Option (which could be None).
意訳:fがOption(Noneの可能性も有り)を返すことになっているという点でmapとわずかに異なる
その微妙な引数の差を、あえてmapとflatMapという名前で区別する意味がわかりませんの。ぷんすかぷん
*)Optionのページ (2.9.1 final)
たとえばmap。これって、よくコレクションにつかうメソッドですの。
でも、そういうメソッドが、実はOption型にも付いてるんですの。(たくさん!)
Option型を使う場合、基本的にはmatchを使って中身を調べるのですけど、それをさぼる方法もいっぱい用意されてますの。きっと、コレクション操作メソッドもその一つですの。
これを使うと、Option型の処理をコレクション操作の中に自然に織り込めるという点で、とっても素敵なのですの。
よく見かけるのは、foreachを使う方法ですの。でも、mapなら値が返ってくるので、より関数型ちっくな書き方ができますの。この辺の選択基準は、コレクションを扱うときと同じですの。
mapやforeachの他にも、filterやcollectなんかもあって、果てはイテレータまで取れるので、もうコレクションの一種だと思ってしまってもいいくらいですの。
ただ、実際のところ、コレクションとは継承関係の繋がりは一切無くて、あくまで同名の専用メソッドを用意しているだけのようなので、全く同じように使えるわけでは無いのですの。ちょっと注意ですの。
それがハッキリわかるのが、mapとflatMapの動作で、次回はそれについてですの。
でも、そういうメソッドが、実はOption型にも付いてるんですの。(たくさん!)
Option型を使う場合、基本的にはmatchを使って中身を調べるのですけど、それをさぼる方法もいっぱい用意されてますの。きっと、コレクション操作メソッドもその一つですの。
これを使うと、Option型の処理をコレクション操作の中に自然に織り込めるという点で、とっても素敵なのですの。
よく見かけるのは、foreachを使う方法ですの。でも、mapなら値が返ってくるので、より関数型ちっくな書き方ができますの。この辺の選択基準は、コレクションを扱うときと同じですの。
mapやforeachの他にも、filterやcollectなんかもあって、果てはイテレータまで取れるので、もうコレクションの一種だと思ってしまってもいいくらいですの。
ただ、実際のところ、コレクションとは継承関係の繋がりは一切無くて、あくまで同名の専用メソッドを用意しているだけのようなので、全く同じように使えるわけでは無いのですの。ちょっと注意ですの。
それがハッキリわかるのが、mapとflatMapの動作で、次回はそれについてですの。
変数をまとめて構造体ちっくにしたクラスと、Map。
どっちが速いか試してみましたの。
まずはMap。
キーは'a~jの10種類、値はそれぞれ0~9ですの。
'aと'jの値を参照する処理を100万回を1セットとして、10回計測。
結果は、
187, 177, 176, 177, 177, 177, 177, 178, 178, 177(ミリ秒)
次に構造体なクラス。
a~jという10個の変数を用意して、値はそれぞれ0~9ですの。
aとjの値を参照する処理を以下同文ですの。
結果は、
7, 2, 4, 4, 4, 4, 4, 3, 4, 4(ミリ秒)
うーん。土台、勝負になってませんの。
Mapのほうが便利そうだと思ったのですけど、もし固定キーで決め打つのなら、あえてMapにしない手もあるかもですの。
・おまけ
定数に名前を付けたら、それはもうキーですの!
と思いこむことにして、
他のコレクションを添字(0番と9番)で参照してみましたの。
List
236, 233, 233, 232, 229, 229, 228, 230, 227, 228(ミリ秒)
ArrayBuffer
48, 47, 47, 47, 45, 46, 46, 47, 47, 47(ミリ秒)
Array(配列)
6, 5, 5, 4, 5, 4, 5, 5, 4, 3
意外にも、Scalaでも配列はかなり低レベルな概念のようですの。
ArrayBufferも相当速いと思うのですけど、さすがに内部処理の有無という壁は厚いですの。
Listは…末尾参照が苦手とはいえ、10項目しか無いのにMapより遅いとは思わなかったですの。。でもまぁ、見方を変えれば、それだけMapが高速ということかも知れませんの。
Scalaは全ての値がオブジェクトなので、
ほかの関数に値を渡すときは必然的に参照渡しになるはずですの。
でも参照渡しだと、引数をつたって元の値をいじれてしまうような…。
それって、わざわざ不変リストとか用意してる意味あるんですの??
と思ったので、試してみましたの。
object Sample {
def main(args: Array[String]){
var list = List(1,2,3)
update(list)
}
def update(obj:List[Int]){
obj = list.updated(1,999)
}
}
へぇぇー。これを動かそうとすると、
代入するところで「reassignment to val」って出て、コンパイル出来ませんの。
なるほどー、仮引数(obj)はvalで宣言してるのと同じ扱いみたいですの。
これなら安心して不変リストを投げ回せますの。ぶんぶーん
登録:
投稿 (Atom)