如何将值元组与函数元组结合起来?

时间:2015-02-18 22:13:42

标签: scala functional-programming scalaz applicative

我有scalaZ可用。

我有(A, B)(A => C, B => D),我希望以简单易读的方式获得(C, D)

我觉得我可以用应用程序做些什么,但我找不到合适的方法。

5 个答案:

答案 0 :(得分:5)

修改

一开始没有得到它,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)

答案 1 :(得分:3)

箭头?类似的东西:

(f *** g)(a, b)

http://eed3si9n.com/learning-scalaz/Arrow.html

答案 2 :(得分:1)

我没有发现scalaz更具可读性。定义自己的功能有什么不对。

def biFunc(valTup:(A,B), funTup:((A)=>C,(B)=>D)):(C,D) = (funTup._1(valTup._1), funTup._2(valTup._2))

答案 3 :(得分:1)

我同意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并获得最高级别的可读性

答案 4 :(得分:0)

自己编写此方法可能是最好的选择:

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)
}

如果你做了很多,你甚至可以增强元组类:

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)