组成部分功能以减少代码长度

时间:2019-04-12 00:34:08

标签: scala partialfunction

我想以特定的方式编写函数以减少代码长度

例如,组成一个简单的add函数:


    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中有办法吗?

2 个答案:

答案 0 :(得分:3)

我对这些表示法有点困惑,例如@Dima ...但是,我经历过这种...试图通过写下直观的方法来理解部分功能来理解它们吗?那是你在做什么吗?因此,我将尝试逐步解释您的情况。

首先,我们必须清楚add3

您提供的这段代码,也许只是为了从头开始理解,不会在scala中编译:

val add3 = (a: Int, b:Int)(c:Int) => a+b+c

确实,我们加入了REPL:

  错误:不是合法的形式参数。注意:元组不能直接   在方法或函数参数中已分解。         创建一个接受Tuple1的参数,         或考虑匹配匿名功能的模式:`{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

希望有帮助...

答案 1 :(得分:1)

我也不确定您的确切意思,但这是您创建具有以下功能的函数的方法:

  • g:具有两个或三个整数的函数,该函数返回一个整数(在您的示例中为add3
  • f:带有一个int的函数,该函数返回一个int(在您的示例中为n

并返回:

  • 另一个函数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)) }