我正在寻找一个函数,该函数在公共域上获取一个函数元组,并将该函数从该域返回到它们各自输出的元组。我假设这样的实用程序要么内置在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)
的函数一样精细。
答案 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解决方案相比,您还松散的是如果存在嵌套元组的结果类型。此外,您还要求每次至少有两个参数中的一个已经是函数。