3

我想做这样的事情List(1 -> 2, 4 -> 5).map(_ + _)来得到List(3, 9)结果。但它不是那样工作的。

与 Scala 的原生“元组”或模式匹配不同,Scalaz 是否提供了一种方便的方式来处理这个问题?

4

5 回答 5

5

Scalaz 不会帮你的。

您可以使用纯 Scala 和@tylerweir 的答案(我真的很喜欢这个解决方案):

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)
于 2012-09-16T16:00:04.100 回答
3

我实际上认为以下内容非常方便 - 甚至比其他答案中的模式匹配版本更好:

List(1 -> 2, 4 -> 5) map Function.tupled(_ + _)

但我会变态,并为稍微不同的问题提供一个 Scalaz 解决方案。假设我们使用的是流而不是列表,并且还假设我们通过压缩以下两个流来构建我们的对流:

val a = Stream(1, 4)
val b = Stream(2, 5)

Scalaz 包含一个用于流的所谓“zip list”应用函子的实例。它不是默认实例,但我们可以适当地“标记”我们的流并像这样使用它:

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 list applicative functor 值得了解。)

于 2012-09-16T16:39:27.533 回答
2

你需要比这更通用的东西吗?

scala> val a = List(1 -> 2, 4 -> 5).map(x => x._1 + x._2)
a: List[Int] = List(3, 9)
于 2012-09-16T14:46:07.033 回答
1

使用小型生产力库可以做到这一点:

List(1 -> 2, 4 -> 5).map(_ $$ (_ + _))
于 2012-12-28T09:43:48.613 回答
0

如果您想使用 scalaz 来执行此操作,那么您可能希望使用 Lenses 来执行此操作。请参阅课程学习 scalaz:第 11 天,以及 Edward Kmett Lenses的讲座视频中捕获的功能命令。在pdf 幻灯片的第 42 页上,Edward 解释了使用带有地图的镜头来纯粹从功能上改变它们。

于 2012-09-17T07:42:16.817 回答