Tupled函数输出

时间:2013-12-07 00:03:36

标签: scala functional-programming scalaz

我正在寻找一个函数,该函数在公共域上获取一个函数元组,并将该函数从该域返回到它们各自输出的元组。我假设这样的实用程序要么内置在Scala中,要么隐藏在Scalaz的某个地方,但我一直无法找到它。

例如,一对函数的特殊情况(并将函数作为单独的参数而不是一对)看起来像:

def pairFunc[I, O1, O2](f: I => O1, g: I => O2): I => (O1, O2) = (x: I) => (f(x), g(x))

有没有办法为任意一元的函数元组实现这个?

编辑:

一个函数类型的方法,其输出看起来像X -> ((A, B), C),其结构看起来像f fZip g fZip h,就像输出为X -> (A, B, C)的函数一样精细。

2 个答案:

答案 0 :(得分:4)

你很幸运,scalaz(7)确实有&&&

  import scalaz._
  import Scalaz._

  val intToString = (i:Int) => i.toString
  val intPlusTwo = (i:Int) => i + 2

  val combined = intToString &&& intPlusTwo

  println(combined(1)) // (1, 3)

你可以继续结合,虽然它确实建立了你的评论建议的元组:

  val combinedMore = intToString &&& intPlusTwo &&& intToString

  println(combinedMore(1)) // ((1,3),1)

答案 1 :(得分:1)

您可以使用chain them

定义自己的隐含和view bounds <%
// Add untupling capacity to a simple pair
implicit class EnrichTuple [A, B, C](f: (Function1[A, B], Function1[A, C])) {
  def untuple = (a: A) => (f._1(a), f._2(a))
}
// Add untupling capacity to a pair where the first member can implicitly be untupled
implicit class EnrichTuple2 [A, C, AB <% Function1[A, B] forSome { type B }](f: (AB, Function1[A, C])) {
  def untuple = (a: A) => (f._1(a), f._2(a))
}
// Add untupling capacity to a pair where the second member can implicitly be untupled
implicit class EnrichTuple3 [A, B, AC <% Function1[A, C] forSome { type C }](f: (Function1[A, B], AC)) {
  def untuple = (a: A) => (f._1(a), f._2(a))
}

val intToString = (i:Int) => i.toString
val intPlusTwo = (i:Int) => i + 2
val intTimesFour = (i: Int) => i * 4

val res1 = (intToString, intPlusTwo).untuple
val res2 = ((intToString, intPlusTwo), intTimesFour).untuple
val res3 = (intToString, (intPlusTwo, intTimesFour)).
res1(1)  // Returns (1, 3)
res2(1)  // Returns ((1, 3),4)
res3(1)  // Returns (1, (3, 4))
val res4 = ((intToString, intTimesFour), (intPlusTwo, intTimesFour )).untuple // Error 

与scalaz解决方案相比,您还松散的是如果存在嵌套元组的结果类型。此外,您还要求每次至少有两个参数中的一个已经是函数。