【问题标题】:Can standard operator be tupled or curried?标准运算符可以元组或柯里化吗?
【发布时间】:2016-11-26 08:17:22
【问题描述】:

以下代码有效:

val ls = Seq("a", "b", "b", "c")

def strEq(a: String, b: String) = a == b
val detectChange = (ls zip ls.tail).map((strEq _). tupled)

是否可以直接使用标准运算符而不是创建 strEq,类似于以下内容?

val detectChange = (ls zip ls.tail).map(== _. tupled)

【问题讨论】:

  • 您的代码无法在 scala 2.11.8 上编译:')' expected but '.' found. [error] val detectChange = (ls zip ls.tail).map(strEq _. tupled).
  • 你需要删除strEq之后的.才能编译。
  • 我看到的最接近内置的东西(有点冗长)是(ls zip ls.tail).map { case (x,y) => x == y }
  • @YuvalItzchakov 那将使用后缀表示法。我改为用括号括起来来修复它。
  • 或者你可以让你的strEqdef strEq(ab: (String, String)) = ab._1 == ab._2 然后val detectChange = bla map strEq 但这很明显...... xD

标签: scala function operators tuples


【解决方案1】:

对于 2 元组的特殊情况,您可以使用:

scala> val ls = Seq("a", "b", "b", "c")
ls: Seq[String] = List(a, b, b, c)

scala> (ls, ls.tail).zipped.map(_ == _)
res0: Seq[Boolean] = List(false, true, false)

其他变种是

scala> (ls zip ls.tail).map{case (a,b) => a == b}
res2: Seq[Boolean] = List(false, true, false)

scala> (ls zip ls.tail).map{((_: String) == (_: String)).tupled}
res5: Seq[Boolean] = List(false, true, false)

scala> (ls zip ls.tail).map(((_ == _): ((String, String) => Boolean)).tupled)
res0: Seq[Boolean] = List(false, true, false)

但它们并不容易理解或更容易编写。 Scalas 类型推断引擎功能不够强大,无法在最后一种情况下推断出正确的类型,因此如果参数类型不匹配,您通常不得不回退以使用模式匹配。

【讨论】:

  • 我认为((_: String) == (_: String)).tupled 回答了我的标题问题“如何对标准运算符进行元组处理” - 它显示了如何获取与运算符对应的函数。它比我希望的更冗长,但它表明它可以做到。
【解决方案2】:

我认为您遇到的问题是== 不是传统意义上的标准运算符,而是一种方法。它不以Function2 的形式存在,所以没有地方可以用.tupled 来调用它,这会产生你正在寻找的东西。 ((_: String) == (_: String)).tupled 有效,因为它 Function2

不确定上述问题是示例还是您实际需要做的事情,但为了好玩,这也有效:

ls sliding 2 map (_.toSet.size == 1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-22
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多