【问题标题】:Idiomatic solution to pipe if管道的惯用解决方案 if
【发布时间】:2021-05-03 10:41:13
【问题描述】:

在我们使用 Scala 2.12 的项目中,我们复制了 the ChainingOps from Scala 2.13。我们经常使用它,我们又增加了一种方法:pipeIf - 当谓词为false 时,我们将值不变地传递。

def pipe[B](f: A => B): B = f(self)

def pipeIf(cond: Boolean)(f: A => A): A = if (cond) f(self) else self

我现在正在尝试移植到 Scala 2.13,这个pipeIf 让我有点担心。此包中的所有其他方法(pipetap)已包含在 Scala 2.13 库中。我宁愿完全移除我们的包裹,但是这个pipeIf 像拇指酸痛一样伸出来。

处理“有条件地管道”的惯用方式是什么?它并没有那么糟糕,但一个抱怨是它阻止了使用下划线形式。用冗长的if/else形式是正常的,还是有别的办法?

val newState = state.pipeIf(dt != 0)(_.simulate(dt))
val newState = state.pipe(state => if (dt != 0) state.simulate(dt) else state )

【问题讨论】:

    标签: scala functional-programming idioms


    【解决方案1】:

    为什么不把它放在一个普遍可用的隐式类中呢?

    implicit class Kestrel[A](private val repr: A) {
      def pipeIf(cond: Boolean)(f: A=>A): A =
        if (cond) f(repr) else repr
      def pipeIf(cond: A=>Boolean)(f: A=>A): A =
        if (cond(repr)) f(repr) else repr
    }
    
    5.pipeIf(_ < 8)(_ * 2)  //res0: Int = 10
    5.pipeIf(false)(_ * 2)  //res1: Int = 5
    

    【讨论】:

    • 如果我没记错的话,我已经把它放在了一个通用的隐式类中。我希望我能够删除整个包,因为此类的所有其他方法都存在于 2.13 标准库中。如果没有简洁的通用方式如何表达这种功能,我猜这个功能将不得不保留。
    • 啊,我明白了。在这种情况下,我建议保持原样。也许它不会孤单。对于应该在库中的链接方法,您可能有其他想法。然后您可以提议将它们添加到 3.1 版本中,届时您可以删除整个包。
    猜你喜欢
    • 2013-05-18
    • 2023-04-03
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 2012-03-30
    • 2021-09-14
    相关资源
    最近更新 更多