2012-12-18 73 views
0

簡化這個傳遞應用程序對於一個給定函數調用F,帶有參數的,B和C,使用函數h調用函數g和我建立的論點,我可以說:如何在斯卡拉

f(a)(b)(c) = g(h(a)(b)(c), i(a)(b)(c)) 

我知道我可以創建一個函數,使得:

g'(h,i)(a)(b)(c) = g(h(a)(b)(c), i(a)(b)(c)) 

使f可以是

f = g'(h,i) 

正是如此申請(a)(b)(c)將產生期望的結果。

,我可以蠻力從強制此(其中F成爲構建):

def build(a: String)(b: String)(c: String) = 
    Message(convA(a)(b)(c), convB(a)(b)(c)) 

到(考慮到H,I是不是要爭論重要,也許這是在斷開連接):

def gDash = { 
    a:String => b: String => c: String => Message(convA(a)(b)(c), convB(a)(b)(c)) 
} 

def build = a:String => b:String => c:String => gDash(a,b,c) 

但我仍然必須指定(a,b,c)的整個輸入。但是我已經從一些應該更加複雜和脆弱的東西變成了更簡單的東西,但是實現實際上是一個更大的混亂!有沒有辦法簡化這個不需要所有這些?

如果我tupleize,這樣的論點:

def gDash = implicit composite:(String,String,String) => Message(convA, convB) 

def convA(composite: s) => ... 
def convB(composite: s) => ... 

def f(a: String)(b: String)(c: String) = gDash((a,b,c)) 

我不知道這其實更好,我覺得我失去了一些東西。

回答

4

方法要求你明確的參數。元組可分配有型的別名,可以用多餘的分型有助於:

type S3 = (String, String, String) 

你可以來回走功能(A, B) => CA => B => C之間用curriedFunction.uncurried

這些給你的工具,你需要做出更加緊湊的功能表示。例如,如果你想要的東西叫做build有形式String => String => String => Whatever,你可以

val build = ((abc: S3) => Message(convA(abc), convB(abc)).curried 

,然後如果你想代替Message你可以做類似

def dash[A,B,C,D,E](g: (A,B) => C)(h: E=>A, i: E=>B): E => C = 
    (e: E) => g(h(e),i(e)) 

,然後uncurry寫gDash在途中如果你想E實際上是三個單獨的字符串參數。