对于给定的函数调用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))
我不确定这实际上是否更好,我觉得我错过了什么。
答案 0 :(得分:4)
方法要求您明确参数。元组可以为它们分配类型别名,这可以帮助进行过多的输入:
type S3 = (String, String, String)
您可以使用(A, B) => C
和A => B => C
在功能curried
和Function.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
实际上是三个独立的字符串参数,那么然后就会出现问题。