2011-10-18 52 views
8

我有两个功能。使用斯拉拉箭头组合?

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

    def applyDiscount(billable: Billable) : 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(_)) 
    } 
+0

你要首先执行'process'然后'功能applyDiscount'? –

+0

是的,确切地说。这两个函数是否使用Scalaz箭头组合?如果是这样,语法是什么? – OleTraveler

回答

9

什么你(简化)是:

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

我能想到的杜安的几种方法g这个。我觉得我的选择是:

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

或者也:

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

然而,有可能是一个pointfree方式 - 虽然未必如此,当然

  • lift是方法Function1W将函数提升到函子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> 
+1

也许'f和然后g.lift [M] .second'。 – missingfaktor

+0

很好的蒸馏,惊人的事情,当你可以*只*看到的类型! – retronym

+0

真棒答案。在完成了repl之后,我完全理解了这里的每一步。应用到我的问题,我想出了这两个解决方案:val bfc = billableBuilder.fromContract(_:User,_:Contract,_:DateTime,_:Option [Order]): - >(applyDiscount(_))。lift [Iterable]和val bfc =(applyDiscount(_))。lift [Iterable] .second apply billableBuilder.fromContract(_:User,_:Contract,_:DateTime,_:Option [Order]) – OleTraveler