Scala Function.tupled 对比 f.tupled
Scala Function.tupled vs f.tupled
我有以下 Scala 代码:
def f(x: Int, y: Int): Option[String] = x*y match {
case 0 => None
case n => Some(n.toString)
}
val data = List((0, 1), (1, 0), (2, 3), (4, -1))
data flatMap {case (x, y) => f(x, y)}
但是,最后一行太冗长了,所以我尝试了所有这些并且 none 编译了它们。
data flatMap f
data flatMap f.tupled
data flatMap Function.tupled(f)
data flatMap {f _}
data flatMap (f _).tupled
data flatMap f(_)
我做错了什么?唯一有效的是:
(data map Function.tupled(f)).flatten
我认为 map
后跟 flatten
总是可以替换为 flatMap
,但是虽然上面的行编译了,但这并没有:
data flatMap Function.tupled(f)
您只能在 returning Options
时使用 flatMap
,因为隐式 [=17] 存在从 Option
到 Iterable
的隐式转换=]. List[(Int, Int)]
上的方法 flatMap
需要一个从 (Int, Int)
到 GenTraversableOnce[Int]
的函数。编译器无法将隐式转换识别为此处的可行选项。您可以通过显式指定通用参数来帮助编译器:
import Function._
data.flatMap[String, Iterable[String]](tupled(f))
//Or
data flatMap tupled[Int, Int, Iterable[String]](f)
相同想法的其他表述也可能允许编译器选择正确的类型和隐式,即使没有显式泛型:
data flatMap (tupled(f _)(_))
data.flatMap (f.tupled(f _)(_))
最后,您可能还想在这里把 collect
和 unlift
一起玩,这也是表达这个逻辑的好方法:
data collect unlift((f _).tupled)
data collect unlift(tupled(f))
Function.unlift
采用 return 一个 Option
的方法并将其转换为 PartialFunction
与原始函数 return 不匹配的地方None
。 collect
采用偏函数并收集偏函数的值(如果在每个元素处都定义了偏函数)。
为了进一步说明上面非常有用的答案,如果您使用 collect
,您可以更进一步,将函数 f 重写为部分函数:
val f: PartialFunction[(Int, Int), String] = {
case (x, y) if x*y != 0 => (x*y).toString
}
然后您可以这样处理您的数据:
data collect f
一般来说,任何 return 作为 Option 的函数都可以 re-written 作为偏函数。在某些情况下,这会变得更整洁,因为您的 case
表达式更少,并且不必将 return 值包装在 Some()
.
中
我有以下 Scala 代码:
def f(x: Int, y: Int): Option[String] = x*y match {
case 0 => None
case n => Some(n.toString)
}
val data = List((0, 1), (1, 0), (2, 3), (4, -1))
data flatMap {case (x, y) => f(x, y)}
但是,最后一行太冗长了,所以我尝试了所有这些并且 none 编译了它们。
data flatMap f
data flatMap f.tupled
data flatMap Function.tupled(f)
data flatMap {f _}
data flatMap (f _).tupled
data flatMap f(_)
我做错了什么?唯一有效的是:
(data map Function.tupled(f)).flatten
我认为 map
后跟 flatten
总是可以替换为 flatMap
,但是虽然上面的行编译了,但这并没有:
data flatMap Function.tupled(f)
您只能在 returning Options
时使用 flatMap
,因为隐式 [=17] 存在从 Option
到 Iterable
的隐式转换=]. List[(Int, Int)]
上的方法 flatMap
需要一个从 (Int, Int)
到 GenTraversableOnce[Int]
的函数。编译器无法将隐式转换识别为此处的可行选项。您可以通过显式指定通用参数来帮助编译器:
import Function._
data.flatMap[String, Iterable[String]](tupled(f))
//Or
data flatMap tupled[Int, Int, Iterable[String]](f)
相同想法的其他表述也可能允许编译器选择正确的类型和隐式,即使没有显式泛型:
data flatMap (tupled(f _)(_))
data.flatMap (f.tupled(f _)(_))
最后,您可能还想在这里把 collect
和 unlift
一起玩,这也是表达这个逻辑的好方法:
data collect unlift((f _).tupled)
data collect unlift(tupled(f))
Function.unlift
采用 return 一个 Option
的方法并将其转换为 PartialFunction
与原始函数 return 不匹配的地方None
。 collect
采用偏函数并收集偏函数的值(如果在每个元素处都定义了偏函数)。
为了进一步说明上面非常有用的答案,如果您使用 collect
,您可以更进一步,将函数 f 重写为部分函数:
val f: PartialFunction[(Int, Int), String] = {
case (x, y) if x*y != 0 => (x*y).toString
}
然后您可以这样处理您的数据:
data collect f
一般来说,任何 return 作为 Option 的函数都可以 re-written 作为偏函数。在某些情况下,这会变得更整洁,因为您的 case
表达式更少,并且不必将 return 值包装在 Some()
.