猫和函数组合
cats and function compositions
我有数据类型:
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]
}
我想实现totalAmountCalculation
像函数组合
val calcTotalAmount = map(x => x.amount) >>> combineAll
为此我写了一些代码:
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
我可以使用哪些猫功能来避免编写 Monad 包装器以在函数组合中使用它?
我希望看到我的代码:
map(x => x + 1) >>>
filter(x < 100) >>>
fold(1)((a,b) => a+b))
如果我对你的问题的理解正确,你希望避免使用包装器 Amount
并且不得不在你的函数定义中的任何地方使用 x => x.amount
。
有几种方法可以解决这个问题。第一种是使用类型别名,就像您对操作所做的那样。这自然会为您提供默认值 Monoid[Int]
,其中 0
代表 zero
并且添加 combine
:
allMoney
.map(_ + 1.0)
.filter(_ > 3.0)
.foldLeft(1.0)(_ + _)
// 13.0
allMoney.combineAll
// 12.0
另一种选择是使用 newtype
库,它使用案例 类:
产生类似的效果
@newsubtype case class Money(amount: Double)
allMoney
.map(_ + 1.0)
.filter(_ > 3.0)
.foldLeft(1.0)(_ + _)
// 13.0
我有数据类型:
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]
}
我想实现totalAmountCalculation
像函数组合
val calcTotalAmount = map(x => x.amount) >>> combineAll
为此我写了一些代码:
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
我可以使用哪些猫功能来避免编写 Monad 包装器以在函数组合中使用它?
我希望看到我的代码:
map(x => x + 1) >>>
filter(x < 100) >>>
fold(1)((a,b) => a+b))
如果我对你的问题的理解正确,你希望避免使用包装器 Amount
并且不得不在你的函数定义中的任何地方使用 x => x.amount
。
有几种方法可以解决这个问题。第一种是使用类型别名,就像您对操作所做的那样。这自然会为您提供默认值 Monoid[Int]
,其中 0
代表 zero
并且添加 combine
:
allMoney
.map(_ + 1.0)
.filter(_ > 3.0)
.foldLeft(1.0)(_ + _)
// 13.0
allMoney.combineAll
// 12.0
另一种选择是使用 newtype
库,它使用案例 类:
@newsubtype case class Money(amount: Double)
allMoney
.map(_ + 1.0)
.filter(_ > 3.0)
.foldLeft(1.0)(_ + _)
// 13.0