如何在Scala中编写此配置逻辑?

时间:2012-07-11 15:09:57

标签: scala applicative

这是我之前question

的后续内容

假设我使用以下逻辑(在准Java中)来获取配置参数MyParam


String myParam = null

if ((myParam = getFromArgs("MyParam")) != null)
   return myParam

if ((myParam = getFromSystemProperties("MyParam")) != null)
   return myParam

if ((myParam = getFromUserConfigFile("MyParam")) != null)
   return myParam

... // and so on

if (myParam == null)
   error("No MyParam")

如何在Scala中编写此逻辑代码?这里适用Applicative吗?

4 个答案:

答案 0 :(得分:8)

List(getFromArgs _, getFromSystemProperties _, getFromUserConfigFile _).map{func=>
  Option(func("MyParam"))
}.reduce(_ orElse _).getOrElse(sys.error("No MyParam"))

结帐scala Option cheatsheet。选项很强大。

答案 1 :(得分:5)

如果您的问题只是语法问题,那么谢飞答案是准确的。

如果您真的在寻找灵活的配置,我建议您热烈关注Typesafe配置项目:https://github.com/typesafehub/config/

答案 2 :(得分:3)

(
  Option(getFromArgs("MyParam")) orElse
  Option(getFromSystemProperties("MyParam")) orElse
  Option(getFromUserConfigFile("MyParam")) getOrElse
  error("No MyParam")
)

答案 3 :(得分:2)

正如我在上面的评论中所指出的,您可以使用Option的“First”monoid实例(实际上您只需要一个半群)来执行此操作 - 例如,使用Scalaz

import scalaz._, Scalaz._

def fo[A](a: A) = Option(a).fst

val param = (
  fo(myParam) |+|
  fo(getFromArgs("MyParam")) |+|
  fo(getFromSystemProperties("MyParam")) |+|
  fo(getFromUserConfigFile("MyParam"))
) getOrElse sys.error("No Param")

它不一定比使用标准库的orElse版本更好,但它突出了相关的抽象(还要注意这个版本是懒惰的 - 如果它们不是getX调用就不会发生'需要)。