I have data types:
import cats.Monoid
import cats.implicits._
object Domain {
case class Money(amount: Double) extends AnyVal {}
implicit val moneyMonoid = new Monoid[Money] {
override def combine(a: Money, b: Money): Money = Money(a.amount + b.amount)
override def empty: Money = Money(0)
}
case class Operation(account: Account, amount: Money) extends AnyRef
type Operations = List[Operation]
}
I want to implement totalAmountCalculation
like function composition
val calcTotalAmount = map(x => x.amount) >>> combineAll
For this I wrote some code:
def map[A, B](F: A => B): List[A] => List[B] = (m: List[A]) => m.map(F)
val combineAll = moneyMonoid.combineAll _
val calcTotalAmount = map[Operation, Money](x => x.amount) >>> combineAll
What cats features I can use for avoid write Monad wrapper for use it in functions composition ?
I want to see my code like:
map(x => x + 1) >>>
filter(x < 100) >>>
fold(1)((a,b) => a+b))
If I understood your question correctly, you want to avoid using the wrapper Amount
and having to use x => x.amount
everywhere in your function definitions.
There are a couple of ways to solve that problem. The first would be to use a type alias, as you did for operations. This will naturally give you the default Monoid[Int]
which has 0
for zero
and addition for combine
:
allMoney
.map(_ + 1.0)
.filter(_ > 3.0)
.foldLeft(1.0)(_ + _)
// 13.0
allMoney.combineAll
// 12.0
Another option would be to use the newtype
library which gives a similar effect using case classes:
@newsubtype case class Money(amount: Double)
allMoney
.map(_ + 1.0)
.filter(_ > 3.0)
.foldLeft(1.0)(_ + _)
// 13.0