如何在Scala中简化此传递应用程序

时间:2012-12-18 19:13:10

标签: scala

对于给定的函数调用f,使用参数a,b和c,使用函数h和i调用函数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)

因此应用f(a)(b)(c)将产生所需的结果。

我可以从(其中f成为构建)强制执行此操作:

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

to(假设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)的整个输入。但是我已经从一些应该更复杂和更脆弱的东西转变为更简单的东西,但实施实际上是一个更大的混乱!有没有办法简化这个并不需要这一切?

如果我将参数元组化,那么:

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))

我不确定这实际上是否更好,我觉得我错过了什么。

1 个答案:

答案 0 :(得分: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

然后如果您想用gDash代替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))
如果你希望E实际上是三个独立的字符串参数,那么

然后就会出现问题。