可使用 scalaz Arrow 进行组合?

发布于 2024-12-10 08:37:52 字数 580 浏览 0 评论 0原文

我有两个功能。

  def process(date: DateTime, invoice: Invoice, user: User, reference: Reference) : (Action, Iterable[Billable])

  def applyDiscount(billable: Billable) : Billable

我怎样才能组合这些,以便我拥有 (DateTime, Invoice, User, Reference) => 的单个函数? (Action, Iterable[Billable])

这是我想要的穷人的方式

  def buildFromInvoice(user: User, order: Invoice, placementDate: DateTime, reference: Reference) = {
    val ab = billableBuilder.fromInvoice(user, order, placementDate, reference)
    (ab._1, ab._2.map(applyDiscount(_))
  }

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

久随 2024-12-17 08:37:52

你所拥有的(简化的)是:

val f: A => (B, M[C]) //M is a Functor
val g: C => C

我可以想出几种方法来做到这一点。我认为我的偏好是:

(a: A) => g.lift[M].second apply f(a)

或者也:

(a: A) => f(a) :-> g.lift[M]  

但是,可能有一种pointfree方式 - 尽管不一定如此,当然

  • liftFunction1W上的一种方法code> 将函数提升到仿函数的领域 M
  • secondMAB 上的一个方法,它将函数应用到 Bifunctor 的右侧
  • :-> 是 Bifunctors 可用的方法,表示函数在 rhs 上的应用。

编辑 - missingfaktor 似乎是正确的说法 f andThen g.lift[M].second 有效:

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>

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 M
  • second 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文