Scalaリスト遊び2(Scala関数型デザインより)
Scalaのリスト遊びの続き。
def reverse[A](l: List[A]): List[A] =
foldLeft(l)(List[A]())((acc:List[A],h:A) => Cons(h,acc))
引数で指定されたリストを逆にする。
def reverse[A](l: List[A]): List[A] =
foldLeft(l)(List[A]())((acc:List[A],h:A) => Cons(h,acc))
引数で指定されたリストを逆にする。
def foldRight2[A,B](l: List[A])(z: B)(f: (A, B) => B): B =
foldLeft(reverse(l))(z)((b,a) => f(a,b))
foldRightをfoldLeftを使って、実装する。 * reverseを使って、リストを逆にして、畳込み関数の引数も逆にして、実行する。
def append2[A](l: List[A], r: List[A]): List[A] = foldRight(l)(r)(Cons(_,_)) def append3[A](a1: List[A], a2: List[A]): List[A] = foldLeft(reverse(a1))(a2)((acc,h) => Cons(h,acc))
foldRightとfoldLeftを使ったappendの再実装。 * foldRightを使った方が素直。アキュムレータの初期値のrリストに対して、lのリストを右から読んでいって、Consでつなげていけばよい。 * Consの定義がCons+Aのため、このような形になる。
def foldRightViaFoldLeft_1[A,B](l: List[A])(z: B)(f: (A,B) => B): B =
foldLeft(l)((b:B) => b)((g,a) => b => g(f(a,b)))(z)
foldRightをfoldLeftを使って、実装する。 の別解。難しい。 * アキュムレータの初期値((b:B) => b)を関数にして、畳込み計算中には、実行させない。のと関数合成((g,a) => b => g(f(a,b)))を作って、初期値(z)を適用させているらしい。 codeday.me
以下は、appendの実行例。
val l = List(1,2,3,4,5) println(s"l:${l}") val l2 = List(6,7,8) println(s"l2:${l2}") val result = append2(l,l2) println(s"result:${result}") val result2 = append3(l,l2) println(s"result2:${result2}")