List(1 -> 2, 4 -> 5).map(_ + _)
結果として得られるように、私はこのようなことをしたいと思っていますList(3, 9)
。しかし、そうはいきません。
Scala のネイティブな「タプル」やパターン マッチングとは異なり、Scalaz は便利な方法でこれを処理する手段を提供しますか?
Scalaz は役に立ちません。
@tylerweir の答えでプレーンな Scala を使用できます (私はこのソリューションが本当に好きです):
scala> val a = List(1 -> 2, 4 -> 5).map(x => x._1 + x._2)
a: List[Int] = List(3, 9)
または、より「一般的な」ものを実行できます(タプルの「サイズ」で機能します):
scala> val a = List(1 -> 2, 4 -> 5, (1,2,3)).map(_.productElements.
collect{case i:Int => i}.sum)
a:List[Int] = List(3,9,6)
または、Shapeless を使用できます (Miles Sabin から: https://github.com/milessabin/shapeless ):
scala> val a = List(1 -> 2, 4 -> 4).map(_.hlisted.toList.sum)
実際、以下は非常に便利だと思います。他の回答のパターンマッチングバージョンよりも優れています。
List(1 -> 2, 4 -> 5) map Function.tupled(_ + _)
しかし、私はひねくれて、わずかに異なる問題に対するScalazソリューションを提供します。リストではなくストリームを使用しているとします。また、次の2つのストリームを圧縮してペアのストリームを構築したとします。
val a = Stream(1, 4)
val b = Stream(2, 5)
Scalazには、ストリーム用の「zipリスト」アプリケーションファンクターと呼ばれるもののインスタンスが含まれています。これはデフォルトのインスタンスではありませんが、ストリームに適切に「タグ付け」して、次のように使用できます。
scala> import scalaz._, std.stream._
import scalaz._
import std.stream._
scala> streamZipApplicative(Tags.Zip(a), Tags.Zip(b))(_ + _).toList
res0: List[Int] = List(3, 9)
そして、あなたは行きます!漠然と関連する問題に対するScalazソリューション。(私は少し皮肉なだけです。私はこのようなものが大好きで、zipリストのアプリケーションファンクターについて知っておく価値があります。)
これよりも一般的なものが必要ですか?
scala> val a = List(1 -> 2, 4 -> 5).map(x => x._1 + x._2)
a: List[Int] = List(3, 9)
小さな生産性ライブラリを使用すると、次のようにすることができます。
List(1 -> 2, 4 -> 5).map(_ $$ (_ + _))
これを行うために scalaz を使用したい場合は、おそらく Lenses でこれを行うことを検討しています。Learning scalaz: Day 11のコースと、Edward Kmett Lenses a Functional Imperativeをビデオで撮影した講義も参照してください。pdf スライドの42 ページで、 Edward はレンズとマップを使用してレンズを純粋に機能的に変更する方法を説明しています。