【问题标题】:Functional Programming Dependencies: How to share dependencies between functions that aren't connected together direct函数式编程依赖关系:如何在未直接连接在一起的函数之间共享依赖关系
【发布时间】:2019-09-19 19:18:49
【问题描述】:

这些不同的功能像这样组合在一起

f1 -> f2 -> f3 -> f4 -> f5

我需要在 f3 周围添加两个新函数 fx 和 fy,如下所示:

f1 -> f2 -> fx -> f3 -> fy -> f4 -> f5

所以我需要对 f3 的参数进行预处理,然后对 f3 的输出进行后处理

这里的函数 fx 进行了更改,fy 将更改恢复回来,但 fy 需要 fx 的其他详细信息才能恢复,例如要知道要恢复到哪些值

问题是函数 fx 需要产生两个输出

first: output that is needed by f3
second: output that is needed by fy

问题: 如何在没有直接连接在一起的函数之间共享依赖关系, 有没有解决这个问题的空间方式/技术?

仅供参考,我使用的是 Java8

【问题讨论】:

  • 可以引入fk,即fx -> f3 -> fy
  • 使用arrows。我不会用 Java 编程。因此,我不知道是否有任何用于基于箭头的计算的 Java 库。快速的谷歌搜索也没有产生任何结果。但是,自己实现它应该不会太难。如果您用一些具体的代码示例更新您的问题,那么也许我可以帮助您。

标签: functional-programming functional-dependencies functional-java


【解决方案1】:

我将对所有函数返回值使用某种类型A;你需要自己整理出真正的类型。

这是你描述的意图:

  • 函数fx会产生两个参数,我们称它们为ab
  • 函数f3 将处理值a 并产生a'
  • 最后,fy 将消耗a'b 并产生c

让我们看看如何实现(我将为类型签名编写伪代码):

  1. fy定义为一个接受两个参数并返回一个参数的函数:

    (A, A) => A
    
  2. fyp(“fy preprocessed”的缩写)定义为一个函数,它接受一些预处理函数p 并执行fy 的逻辑,但第一个参数使用p 进行预处理。我们将其写成P => FY的形式,其中P是预处理函数的类型签名,FYfy的类型签名:

    P => FY, which expands to  
    (A => A) => (A, A) => A
    

    所以这个函数的实现应该以A => A类型的预处理函数p作为输入,执行fy的逻辑(这是右手边,(A, A) => A...注意它是怎么做的对应fy的签名),但是在执行逻辑之前,它将fy的第一个参数映射到p。这里有一些 Scala 实现供参考(我不太擅长 Java):

    val fyp: (A => A) => ((A, A)) => A =              
      f => fyuParams => performFyLogic((f(fyuParams._1), fyuParams._2))  
    

    其中performFyLogic 是您的fy 函数的实际处理逻辑。

  3. 将最终组合定义为:

    f1 -> f2 -> fx -> fyp(f3)
    

这里是完整的 Scala 实现供参考(同样,不太了解 Java 8):

val f1: Int => Int = _ + 1
val f2: Int => Int = _ + 2
val f3: Int => Int = _ + 3

val fx: Int => (Int, Int) = i => (i + 4, i + 5)

// let's assume that the original fy simply sums up its two parameters
val fyp: (Int => Int) => ((Int, Int)) => Int =
  f => fyArgs => f(fyArgs._1) + fyArgs._2

val composed1 = f1 andThen f2 andThen f3
println(composed1(42)) // 48

val composed2 = f1 andThen f2 andThen fx andThen fyp(f3)
println(composed2(42)) // 102

// because:
// f1 -> f2 -> fx = (42 + 1 + 2 + 4, 41 + 1 + 2 + 5) = (49, 50)
// fyp(f3)((49, 50)) = (49 + 3) + 50 = 102    

【讨论】:

    【解决方案2】:

    我通过创建 fk 函数来解决这个问题,该函数通过调用 fx 之前和之后调用 fy 来包装 f3,这样我就能够共享所需的状态位,这类似于 Aadit 建议的箭头。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-30
      • 2015-11-06
      • 2015-07-20
      相关资源
      最近更新 更多