scala - 链式 + Scala 选项

标签 scala functional-programming

我有 configurer支持像这样的链式:

val configurer = Configurer("init").propA("a").propB(3).propC("bla-bla")

这是我无法更改的第 3 方库。

我有我的

case class Config(propA: Option[String], propB: Option[Int], propC: Option[String])



现在我需要构建我的 configurer给定 config对象,方法 propX如果在 config 中设置了相应的值,则应调用.

以功能方式做到这一点的最佳方法是什么?

我不喜欢这个
val configurer = Configurer("init")
val withPropA = config.propA.map(configurer.propA).getOrElse(configure)
val withPropB = config.propB.map(configurer.propB).getOrElse(withPropA)
val withPropC = config.propC.map(configurer.propC).getOrElse(withPropB)

只是觉得应该有一种优雅的方式。

最佳答案

由于您特别询问以功能方式执行此操作,因此我建议对每个转换 Some 的选项使用折叠。进入所需的功能和 None进入 identity :

config.propA.fold(identity[Configurer] _)(a => _ propA a) andThen
config.propB.fold(identity[Configurer] _)(b => _ propB b) andThen
config.propC.fold(identity[Configurer] _)(c => _ propC c)

如果你真的很喜欢冒险,你可以用 Scalaz 让它更优雅一点:
import scalaz._, Scalaz._

config.propA.map(a => Endo[Configurer](_ propA a)).orZero |+|
config.propB.map(b => Endo[Configurer](_ propB b)).orZero |+|
config.propC.map(c => Endo[Configurer](_ propC c)).orZero

不过,在实际代码中,您可能希望使用 Eugene 的解决方案,因为您只是在包装一个并不理想的 API,而且重要的是从现在开始变得清晰。

关于scala - 链式 + Scala 选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26181024/

相关文章:

scala - 在函数中执行函数时的警告

带有 setTimeout 的 Javascript 回调

functional-programming - 对 Substitution/`ap` 类型签名和不同实现的理解困惑(函数式编程)

swift - 不可变结构比可变结构有什么好处?

functional-programming - 用 Racket 构建 map

scala - 函数特征和隐式参数

scala - Play Framework 2.4.1 : How to get configuration values just after configuration file has been loaded

scala - 在标准元组上重现 HList 样式操作的无形状示例

dictionary - 如何在 Common Lisp 中映射函数?

java - 相当于Java中Scala中的summaryStatistics