部分函数的组合以减少代码长度
Composition of partial functions to reduce code length
我想以特定的方式编写函数以减少代码长度
例如编写一个简单的添加函数:
val add3 = (a: Int, b:Int) => (c:Int) => a+b+c
val composed = (a:Int, b:Int) => n:add3(a, b) => n(1) + n(2) + n(3)
这将非常有用,这样我就不必每次都将 a 和 b 作为参数传递。
在 Scala 中有没有办法做到这一点?
我对这些符号有点困惑,比如@Dima……但是,我经历过这种……试图通过写下直观的方式来处理部分功能……理解它们?那是你在做什么?所以我会一步步为你解读。
首先我们要明确add3
你给出的这段代码,我想可能只是从头开始理解,不会在 scala 中编译:
val add3 = (a: Int, b:Int)(c:Int) => a+b+c
的确,我们得到了一个 REPL:
error: not a legal formal parameter. Note: Tuples cannot be directly
destructured in method or function parameters.
Either create a single parameter accepting the Tuple1,
or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
val add3 = (a: Int, b:Int)(c:Int) => a+b+c
^
但我可能已经明白你想建议的想法了...
add3
是这样一种方法:
def add3Method (a: Int, b:Int)(c:Int) = a+b+c
然后可以部分应用:
val add3 = add3Method _
或者它可以直接是一个函数,如:
val add3 = (a: Int, b:Int) => (c: Int) => a+b+c
无论哪种方式,它都给出了一个 (Int, Int) => Int => Int
类型的函数。 这是你想要的吗?
那我们就得搞清楚“composed
”
你给出的这段代码,我想可能只是从头开始理解,不会在 scala 中编译 也不会:
val composed = (a:Int, b:Int) => n:add3(a, b) => n(1) + n(2) + n(3)
但我可能...好吧,至少,我可能也有你想要建议的想法...
(a) 关闭?
你表达它的方式让我觉得就像一个闭包,最终意味着 composed
有一个类型 (Int, Int) => Int
。 你是这个意思吗?
(b) 一个采用 add3
?
类型的函数
或者,您只希望 add3
是传递给 composed
的任何相同类型的函数,我假设是 (Int, Int) => Int => Int
。 你是这个意思吗?
那么,你有一些方法可以定义“composed
”
通过映射或中间变量。
闭包,中间变量方式
val composedCI = (a:Int, b:Int) => { val n = add3(a,b); n(1) + n(2) + n(3)}
闭包、映射方式
val composedCM = (a:Int, b:Int) => (1 to 3).map(add3(a,b)).sum
作为参数add3
,中间变量方式
val composedTI = (a:Int, b:Int) => (myAdd3asAnArg: (Int, Int) => Int => Int) => { val n = myAdd3asAnArg(a,b); n(1) + n(2) + n(3) }
作为参数add3
,映射方式
val composedTM = (a:Int, b:Int) => (myAdd3asAnArg: (Int, Int) => Int => Int) => (1 to 3).map(myAdd3asAnArg(a,b)).sum
使用“composed
”
println(composedCM(4,5))
println(composedCI(4,5))
println(composedTM(4,5)(add3))
println(composedTI(4,5)(add3))
会给予
33
33
33
33
希望对您有所帮助...
我也不确定你到底是什么意思,但这是你可以创建一个函数的方法:
- g:一个接受两个或三个整数的函数,即 returns 一个整数(在您的示例中为
add3
)
- f:一个接受一个 int 的函数,即 returns 一个 int(在您的示例中为
n
)
和returns:
- 另一个函数 g(f),采用与 g 相同的输入,但首先应用 f
// type aliases
type TwoOrThreeIntFn = (Int, Int) => Int => Int
type OneIntFn = Int => Int
// create a function that takes two functions and returns their composition
def composition(f: OneIntFn)(g: TwoOrThreeIntFn):TwoOrThreeIntFn = { (a:Int, b:Int) => (c:Int) => g(f(a), f(b))(f(c)) }
我想以特定的方式编写函数以减少代码长度
例如编写一个简单的添加函数:
val add3 = (a: Int, b:Int) => (c:Int) => a+b+c
val composed = (a:Int, b:Int) => n:add3(a, b) => n(1) + n(2) + n(3)
这将非常有用,这样我就不必每次都将 a 和 b 作为参数传递。
在 Scala 中有没有办法做到这一点?
我对这些符号有点困惑,比如@Dima……但是,我经历过这种……试图通过写下直观的方式来处理部分功能……理解它们?那是你在做什么?所以我会一步步为你解读。
首先我们要明确add3
你给出的这段代码,我想可能只是从头开始理解,不会在 scala 中编译:
val add3 = (a: Int, b:Int)(c:Int) => a+b+c
的确,我们得到了一个 REPL:
error: not a legal formal parameter. Note: Tuples cannot be directly destructured in method or function parameters. Either create a single parameter accepting the Tuple1, or consider a pattern matching anonymous function: `{ case (param1, param1) => ... } val add3 = (a: Int, b:Int)(c:Int) => a+b+c ^
但我可能已经明白你想建议的想法了...
add3
是这样一种方法:
def add3Method (a: Int, b:Int)(c:Int) = a+b+c
然后可以部分应用:
val add3 = add3Method _
或者它可以直接是一个函数,如:
val add3 = (a: Int, b:Int) => (c: Int) => a+b+c
无论哪种方式,它都给出了一个 (Int, Int) => Int => Int
类型的函数。 这是你想要的吗?
那我们就得搞清楚“composed
”
你给出的这段代码,我想可能只是从头开始理解,不会在 scala 中编译 也不会:
val composed = (a:Int, b:Int) => n:add3(a, b) => n(1) + n(2) + n(3)
但我可能...好吧,至少,我可能也有你想要建议的想法...
(a) 关闭?
你表达它的方式让我觉得就像一个闭包,最终意味着 composed
有一个类型 (Int, Int) => Int
。 你是这个意思吗?
(b) 一个采用 add3
?
类型的函数
或者,您只希望 add3
是传递给 composed
的任何相同类型的函数,我假设是 (Int, Int) => Int => Int
。 你是这个意思吗?
那么,你有一些方法可以定义“composed
”
通过映射或中间变量。
闭包,中间变量方式
val composedCI = (a:Int, b:Int) => { val n = add3(a,b); n(1) + n(2) + n(3)}
闭包、映射方式
val composedCM = (a:Int, b:Int) => (1 to 3).map(add3(a,b)).sum
作为参数add3
,中间变量方式
val composedTI = (a:Int, b:Int) => (myAdd3asAnArg: (Int, Int) => Int => Int) => { val n = myAdd3asAnArg(a,b); n(1) + n(2) + n(3) }
作为参数add3
,映射方式
val composedTM = (a:Int, b:Int) => (myAdd3asAnArg: (Int, Int) => Int => Int) => (1 to 3).map(myAdd3asAnArg(a,b)).sum
使用“composed
”
println(composedCM(4,5))
println(composedCI(4,5))
println(composedTM(4,5)(add3))
println(composedTI(4,5)(add3))
会给予
33
33
33
33
希望对您有所帮助...
我也不确定你到底是什么意思,但这是你可以创建一个函数的方法:
- g:一个接受两个或三个整数的函数,即 returns 一个整数(在您的示例中为
add3
) - f:一个接受一个 int 的函数,即 returns 一个 int(在您的示例中为
n
)
和returns:
- 另一个函数 g(f),采用与 g 相同的输入,但首先应用 f
// type aliases
type TwoOrThreeIntFn = (Int, Int) => Int => Int
type OneIntFn = Int => Int
// create a function that takes two functions and returns their composition
def composition(f: OneIntFn)(g: TwoOrThreeIntFn):TwoOrThreeIntFn = { (a:Int, b:Int) => (c:Int) => g(f(a), f(b))(f(c)) }