I have scalaZ available.
I have an (A, B)
and a (A => C, B => D)
, I'd like to get a (C, D)
in a simple and readable way.
I feel like there's something I can do with applicatives but I can't find the right methods.
I have scalaZ available.
I have an (A, B)
and a (A => C, B => D)
, I'd like to get a (C, D)
in a simple and readable way.
I feel like there's something I can do with applicatives but I can't find the right methods.
Didn't get it at first, that the OP has tuple of functions. In such case as suggested in comments this should work:
val in = ("1", 2)
val fnT = ((s: String) => s.toInt, (i: Int) => i.toString)
val out = (in.bimap[Int, String] _).tupled(fnT)
If you have two functions and want to apply them on tuple, you should be able to do:
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)
funTuple appliedTo tuple2
–
Scoot tupled
to bimap
and then pass in the tuple of functions –
Galleass ab.bimap.tupled
- maybe because bimap is supplied via implicit? I'm not sure. The console gives me a different error, scala> ab.bimap.tupled(fs)
=> error: missing arguments for method bimap in class BifunctorOps; follow this method with
_' if you want to treat it as a partially applied function, but I can't find any combination of
_` to make it work –
Trahern scalaz
so I didn't test that before I commented, it just seemed like it would work! Maybe it's the implicit, like you said. –
Galleass in.bimap[Int, String] _ tupled tupledFuncs
–
Galleass I'm not finding scalaz more readable. Whats wrong with defining your own function.
def biFunc(valTup:(A,B), funTup:((A)=>C,(B)=>D)):(C,D) = (funTup._1(valTup._1), funTup._2(valTup._2))
I agree with Lionel Port, but you could make it more readable via:
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)
}
used like:
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
So, in the end you end up with funTuple applyTo tuple
and gain your top level readability
Writing this method yourself might be the best bet:
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)
}
And if you're doing this a lot, you might even enhance the tuple 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)
}
}
So that you can do:
val func1: Int => Int = x => x * x
val func2: Int => String = x => x.toString
val tupledFuncs = func1 -> func2
(1, 2).bimap(tupledFuncs)
© 2022 - 2024 — McMap. All rights reserved.
bimap
from the Bifunctor package – Lora