【问题标题】:Scala: map on zipped lists unclearScala:压缩列表上的地图不清楚
【发布时间】:2016-05-22 00:14:15
【问题描述】:

为了一个任务,我必须写一个函数

zipWith[A,B,C](f:Function2[A,B,C], l1:List[A], l2:List[B]) : List[C]

接受两个列表和一个函数并返回另一个列表。 例如:

zipWith((x: Int, y: Int) => x + y, List(1, 2, 3), List(4, 5, 6))
    → List(5, 7, 9)

所以我开始压缩 l1 和 l2 并尝试映射结果列表:

(l1 zip l2) map ((x:A, y:B) => f(x,y))

给出“类型不匹配:找到:(A,B) => C,需要:((A,B)) => ?”

我研究了一下,找到了两个解决方案,但我不明白为什么会这样:

(l1, l2).zipped map ((x:A, y:B)) => f(x,y))

我签入了 REPL:

l1 zip l2 => List[(A, B)] 

同时

(l1, l2).zipped => scala.runtime.Tuple2Zipped[A,List[A],B,List[B]] 

在我看来,哪个看起来不像 ((A,B)) 而不是 (A,B)?

谁能解释一下?

另一种解决方案,

(l1 zip l2) map { case (x, y) => f(x, y) }

涉及一种隐藏类型的模式匹配(或者我理解),我不应该将其用于分配。

【问题讨论】:

  • 确实,这是重复的……但这个问题比另一个 IMO 更好地表达和提出。
  • 现在,如果我要设置分配,我也不会允许 zip (在我看来非常像实现类似地图功能的分配,而不仅仅是 zip 并使用map. 如果列表长度不同,你的函数应该做什么?
  • @TheArchetypalPaul 没有关于这种行为的消息。作业内容如下: 使用 map 和/或 fold 定义以下非递归函数(没有模式匹配和递归调用)。您可以使用“List”类的任何方法,但不能使用自己的辅助方法。另一个问题很可能确实来自我的一位同学。抱歉重复了。
  • @ClausRuepp,感谢您提供详细信息。我只是在猜测/“猜测”。

标签: list scala dictionary zip


【解决方案1】:

List.zip 返回一个元组列表,因此,当您 .map 它时,它需要一个函数,该函数采用 Tuple2 类型的单个参数,而不是您想要的两个单独的参数。如果不能使用模式匹配,可以显式解构元组:l1 zip l2 map { ab => f(ab._1, ab._2) }

或者,正如您所发现的,您可以使用(l1, l2).zipped。这将返回一个特殊类型Tuple2Zipped,而不是像其他情况那样只是一个集合。这种特殊类型有一个成员方法map,它接受一个需要两个参数的函数,这正是您所需要的。这就是它起作用的原因。

【讨论】:

  • 谢谢,这清除了它。为什么 Tuple2Zipped 被表示为 T2Z[A,List[A],B,List[B]] 但行为更像我期望 Tuple2 (A, B) 的行为?
  • 因为你的期望是错误的 :) Tuple2 根本没有任何 map 函数。
  • 你也可以写l1 zip l2 map f.tupled
猜你喜欢
  • 1970-01-01
  • 2014-05-23
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 1970-01-01
相关资源
最近更新 更多