如何将值元组与函数元组结合起来?
How can I combine a tuple of values with a tuple of functions?
我有可用的 scalaZ。
我有一个 (A, B)
和一个 (A => C, B => D)
,我想以一种简单易读的方式得到一个 (C, D)
。
我觉得我可以用应用程序做一些事情,但我找不到合适的方法。
编辑
一开始没明白,OP 有函数元组。在评论中建议的这种情况下,这应该有效:
val in = ("1", 2)
val fnT = ((s: String) => s.toInt, (i: Int) => i.toString)
val out = (in.bimap[Int, String] _).tupled(fnT)
旧
如果你有两个函数并想将它们应用到元组上,你应该可以这样做:
import scalaz._
import Scalaz._
val in = ("1", 2)
val sToi = (s: String) => s.toInt
val iTos = (i: Int) => i.toString
val out = sToi <-: in :-> iTos
// or
val out1 = in.bimap(sToi, iTos)
// or
val out2 = (sToi *** iTos)(in)
箭?类似于:
(f *** g)(a, b)
我没有发现 scalaz 更具可读性。自己定义函数有什么问题。
def biFunc(valTup:(A,B), funTup:((A)=>C,(B)=>D)):(C,D) = (funTup._1(valTup._1), funTup._2(valTup._2))
我同意 Lionel Port 的观点,但您可以通过以下方式使其更具可读性:
case class BiFun[A,B,C,D](f1:A=>C, f2: B=>D){
def applyTo(a: (A,B)) = (f1(a._1), f2(a._2))
}
object BiFun{
implicit def toBiFun(a: (A=>C, B=>D)) = BiFun(a._1, a._2)
}
像这样使用:
import BiFun._
val ab = (A(1), B(2))
val ac = (x: A) => C(x.i+2)
val bd = (x: B) => D(x.i+2)
val bifn = (ac, bd)
bifn applyTo ab
所以,最后你得到 funTuple applyTo tuple
并获得最高水平的可读性
自己编写此方法可能是最好的选择:
def bimap[A,B,C,D](vals:(A, B), funcs:(A=>C, B=>D)):(C,D) = {
val ((func1, func2), (val1, val2)) = funcs -> vals
func1(val1) -> func2(val2)
}
如果你经常这样做,你甚至可以增强元组 class:
implicit class EnhancedTuple2[A, B](val vals: (A, B)) extends AnyVal {
def bimap[C, D](funcs: (A=>C, B=>D)) = {
val ((func1, func2), (val1, val2)) = funcs -> vals
func1(val1) -> func2(val2)
}
}
这样你就可以做到:
val func1: Int => Int = x => x * x
val func2: Int => String = x => x.toString
val tupledFuncs = func1 -> func2
(1, 2).bimap(tupledFuncs)
我有可用的 scalaZ。
我有一个 (A, B)
和一个 (A => C, B => D)
,我想以一种简单易读的方式得到一个 (C, D)
。
我觉得我可以用应用程序做一些事情,但我找不到合适的方法。
编辑
一开始没明白,OP 有函数元组。在评论中建议的这种情况下,这应该有效:
val in = ("1", 2)
val fnT = ((s: String) => s.toInt, (i: Int) => i.toString)
val out = (in.bimap[Int, String] _).tupled(fnT)
旧
如果你有两个函数并想将它们应用到元组上,你应该可以这样做:
import scalaz._
import Scalaz._
val in = ("1", 2)
val sToi = (s: String) => s.toInt
val iTos = (i: Int) => i.toString
val out = sToi <-: in :-> iTos
// or
val out1 = in.bimap(sToi, iTos)
// or
val out2 = (sToi *** iTos)(in)
箭?类似于:
(f *** g)(a, b)
我没有发现 scalaz 更具可读性。自己定义函数有什么问题。
def biFunc(valTup:(A,B), funTup:((A)=>C,(B)=>D)):(C,D) = (funTup._1(valTup._1), funTup._2(valTup._2))
我同意 Lionel Port 的观点,但您可以通过以下方式使其更具可读性:
case class BiFun[A,B,C,D](f1:A=>C, f2: B=>D){
def applyTo(a: (A,B)) = (f1(a._1), f2(a._2))
}
object BiFun{
implicit def toBiFun(a: (A=>C, B=>D)) = BiFun(a._1, a._2)
}
像这样使用:
import BiFun._
val ab = (A(1), B(2))
val ac = (x: A) => C(x.i+2)
val bd = (x: B) => D(x.i+2)
val bifn = (ac, bd)
bifn applyTo ab
所以,最后你得到 funTuple applyTo tuple
并获得最高水平的可读性
自己编写此方法可能是最好的选择:
def bimap[A,B,C,D](vals:(A, B), funcs:(A=>C, B=>D)):(C,D) = {
val ((func1, func2), (val1, val2)) = funcs -> vals
func1(val1) -> func2(val2)
}
如果你经常这样做,你甚至可以增强元组 class:
implicit class EnhancedTuple2[A, B](val vals: (A, B)) extends AnyVal {
def bimap[C, D](funcs: (A=>C, B=>D)) = {
val ((func1, func2), (val1, val2)) = funcs -> vals
func1(val1) -> func2(val2)
}
}
这样你就可以做到:
val func1: Int => Int = x => x * x
val func2: Int => String = x => x.toString
val tupledFuncs = func1 -> func2
(1, 2).bimap(tupledFuncs)