【问题标题】:Composition of partial functions to reduce code length部分函数的组合以减少代码长度
【发布时间】:2019-04-12 23:39:55
【问题描述】:

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

例如编写一个简单的 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)

这将非常有用,因此我不必每次都将 ab 作为参数传递。

在 Scala 中有没有办法做到这一点?

【问题讨论】:

  • 对不起,我真的很累在这里提出一个有用的问题,但我唯一能想到的是:嗯?
  • 我不能不同意@Dima ...如果你想在这一点上减少代码长度,你必须得到一个编译和运行的代码,然后然后重构它: make it workthen make it clean 。你知道...
  • 另外,对于大多数不熟悉的人来说,部分函数太抽象了,不能使用相关的 scala 特定术语来首先解释您的问题,例如 methodcurryingclosure... 大多数时候,学习使用它们,肯定会帮助你。好吧,它在某些时候对我有用......

标签: scala partialfunction


【解决方案1】:

我对这些符号有点困惑,比如@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

希望对你有帮助...

【讨论】:

  • 闭包映射方式正是我想要的,谢谢!
  • 太棒了!您介意将答案标记为正确然后@nbreizh 吗?完成后,我将尽可能地编辑您的问题以使其清晰。 (参见meta.stackexchange.com/questions/147531/…
【解决方案2】:

我也不确定你到底是什么意思,但你可以这样创建一个函数:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多