2012年2月24日金曜日

mapBetween関数Scala版 その2

前回のコードをrpscalaの方々に見て頂いたところ、「それ、slidingでできるよ!」と教えていただいたので修正。

object mapBetween2 {
def main(args:Array[String]) = {
val range = 1 to 10
println(mapBetween(range)(_+_) mkString ",")
println(mapBetween(range)(_*_) mkString ",")
println(mapBetween(range)(_-_) mkString ",")
}
def mapBetween[A,B,T>:A](seq:Seq[A])(f:(T,T)=>B): Iterator[B] = {
seq.sliding(2).map(s=>f(s(0),s(1)))
}
}

sliding関数は引数で指定された個数を1つのブロックとして、sliding windowを提供する。例えばSeq(1,2,3,4)に対してsliding(2)を呼び出すと、Seq(1,2),Seq(2,3),Seq(3,4)と返すIteratorが返される。sliding(3)ならSeq(1,2,3),Seq(2,3,4)となる。
これはmapBetween関数でやりたいことほぼそのものなので、結果としてえらいシンプルになってしまった。

前回適用する関数に対して型推論が効かないと愚痴ったが、これはカリー化することで対応できることを教えてもらった。カリー化前だと型パラメタAとTを同時に推論しなければならず、それが上手くいかない原因だった模様。カリー化することで先に型Aが決定するため、型Tが上手く推論できるようになるらしい。嘘かも。型推論はもうちょっとまともに勉強したいなぁ。。。

0 件のコメント:

コメントを投稿