I have two functions.
def process(date: DateTime, invoice: Invoice, user: User, reference: Reference) : (Action, Iterable[Billable])
def applyDiscount(billable: Billable) : Billable
How can I compose these so that I have a single function of (DateTime, Invoice, User, Reference) => (Action, Iterable[Billable])
Here is the poor mans way of what I want
def buildFromInvoice(user: User, order: Invoice, placementDate: DateTime, reference: Reference) = {
val ab = billableBuilder.fromInvoice(user, order, placementDate, reference)
(ab._1, ab._2.map(applyDiscount(_))
}
What you have (simplifying) is:
val f: A => (B, M[C]) //M is a Functor
val g: C => C
I can think of a few ways of doing this. I think my preference is:
(a: A) => g.lift[M].second apply f(a)
Or also:
(a: A) => f(a) :-> g.lift[M]
However, there is possibly a pointfree way - although not necessarily so, of course
lift
is a method on Function1W
which lifts the function into the realm of the functor Msecond
is a method on MAB
which applies the function down the right-hand-side of a Bifunctor
:->
is a method available to Bifunctors
denoting the application of a function on the rhs.EDIT - missingfaktor appears to be correct in saying f andThen g.lift[M].second
works:
scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._
scala> case class A(); case class B(); case class C()
defined class A
defined class B
defined class C
scala> lazy val f: A => (B, List[C]) = sys.error("")
f: A => (B, List[C]) = <lazy>
scala> lazy val g: C => C = sys.error("")
g: C => C = <lazy>
Pointfree:
scala> lazy val h = f andThen g.lift[List].second
h: A => (B, List[C]) = <lazy>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With