我希望像List(1 -> 2, 4 -> 5).map(_ + _)
那样做一些事情来获得List(3, 9)
。但它不会那样工作。
与Scala的原生“tupled”或模式匹配不同,Scalaz是否提供了以方便的方式处理此问题的方法?
答案 0 :(得分:5)
你可以使用普通的Scala和@tylerweir的答案(我真的很喜欢这个解决方案):
scala> val a = List(1 -> 2, 4 -> 5).map(x => x._1 + x._2)
a: List[Int] = List(3, 9)
或者你可以做更多的"泛型"东西(它适用于任何tupple" size"):
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)
答案 1 :(得分:3)
我实际上认为以下特别方便 - 甚至比其他答案中的模式匹配版本更好:
List(1 -> 2, 4 -> 5) map Function.tupled(_ + _)
但是我会有悖常理并为稍微不同的问题提供Scalaz解决方案。假设我们正在使用流而不是列表,并且假设我们通过压缩以下两个流来构建我们的对流:
val a = Stream(1, 4)
val b = Stream(2, 5)
Scalaz包含了一个名为the "zip list" applicative functor的流的实例。它不是默认实例,但我们可以适当地“标记”我们的流并使用它:
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解决方案。 (我只是有点讽刺 - 我喜欢这些东西,而且拉链列表应用程序的编写器值得了解。)
答案 2 :(得分:2)
你需要比这更通用的东西吗?
scala> val a = List(1 -> 2, 4 -> 5).map(x => x._1 + x._2)
a: List[Int] = List(3, 9)
答案 3 :(得分:1)
使用小型生产力库embrace可以这样做:
List(1 -> 2, 4 -> 5).map(_ $$ (_ + _))
答案 4 :(得分:0)
如果您想使用scalaz来执行此操作,那么您可能希望使用镜头执行此操作。 查看课程Learning scalaz: Day 11,以及Edward Kmett Lenses a Functional Imperative在视频中捕获的讲座。在the pdf slides的第42页,Edward解释了使用带有地图的镜头来完全改变它们的功能。