関数型の醍醐味は再帰ときいてやってきました。
ということで書いてみる。
補足すると、isEmptyはリストが空かどうか判別する関数で、headはリストの先頭の要素を、tailは先頭から二番目以降のサブリストを取り出す関数。前にもやったけど、Nilが返る=空のリストが返る。
というかここにきて::が活きてきますなー
add的なものがないのに::があるってなんだ?って思ったけどフラグだったわけですね。はい。
Javaだとこうはいかねーなー
当然だけど各要素に適用する処理を関数として渡せる。
ちなみにリストの操作をするときこんなifとか使ってるのはスマートじゃないっぽい。
どうするかというと、パターンマッチを使う。
x::xsみたいな感じでcaseを定義できるのか。これどういう動きしてるのかよくわからん。。。
これ便利だなーって思ったけどそれをそもそも用意しちゃったのがmapメソッドとかってことか。
つか関数とかメソッドとかまだあれなんだがどう使い分ければいいんだ。
ということで書いてみる。
scala> def foo(l:List[Int]):List[Int] = {
| if(l.isEmpty) Nil
| else l.head * 10 :: foo(l.tail)
| }
foo: (List[Int])List[Int]
scala> foo(List(1,2,3,4,5))
res22: List[Int] = List(10, 20, 30, 40, 50)補足すると、isEmptyはリストが空かどうか判別する関数で、headはリストの先頭の要素を、tailは先頭から二番目以降のサブリストを取り出す関数。前にもやったけど、Nilが返る=空のリストが返る。
というかここにきて::が活きてきますなー
add的なものがないのに::があるってなんだ?って思ったけどフラグだったわけですね。はい。
Javaだとこうはいかねーなー
当然だけど各要素に適用する処理を関数として渡せる。
scala> def foo(l:List[Int])(f:(Int) => Int):List[Int] = {
| if(l.isEmpty) Nil
| else f(l.head) :: foo(l.tail)(f)
| }
foo: (List[Int])((Int) => Int)List[Int]
scala> val bar = (x:Int) => x + 5
bar: (Int) => Int = <function>
scala> foo(List(1,2,3,4,5))(bar)
res23: List[Int] = List(6, 7, 8, 9, 10)ちなみにリストの操作をするときこんなifとか使ってるのはスマートじゃないっぽい。
どうするかというと、パターンマッチを使う。
scala> def foo(l:List[Int])(f:(Int) => Int):List[Int] = l match {
| case Nil => l
| case x::xs => f(x)::foo(xs)(f)
| }
foo: (List[Int])((Int) => Int)List[Int]
scala> foo(List(2,4,6,8,10))(bar)
res24: List[Int] = List(7, 9, 11, 13, 15)x::xsみたいな感じでcaseを定義できるのか。これどういう動きしてるのかよくわからん。。。
これ便利だなーって思ったけどそれをそもそも用意しちゃったのがmapメソッドとかってことか。
つか関数とかメソッドとかまだあれなんだがどう使い分ければいいんだ。