2011-10-18 53 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