我有Map[String,String]
个配置值。我想提取一系列密钥,并提供有意义的错误消息,如果缺少任何密钥。例如:
val a = Map("url"->"http://example.com", "user"->"bob", "password"->"12345")
说我想将其转换为案例类:
case class HttpConnectionParams(url:String, user:String, password: String)
现在,我可以简单地使用for循环来提取值:
for(url <- a.get("url");
user <- a.get("user");
password <- a.get("password")) yield {
HttpConnectionParams(url,user,password)
}
获得Option[HttpConnectionParams]
。这很干净,除非我得到None
,否则我不知道遗漏了什么。我想提供这些信息。
输入scalaz。我使用的是7.1.3版本。
从我能够组合起来(一个很好的参考是here)我可以使用析取:
for(url <- a.get("url") \/> "Url must be supplied";
user <- a.get("user") \/> "Username must be supplied";
password <- a.get("password") \/> "Password must be supplied") yield {
HttpConnectionParams(url,user,password)
}
这很好,因为现在我收到一条错误消息,但这是railway oriented,因为它在第一次失败时停止。如果我想获得所有错误怎么办?让我们使用验证和应用程序构建器(又名&#34; | @ |&#34;):
val result = a.get("url").toSuccess("Url must be supplied") |@|
a.get("username").toSuccess("Username must be supplied") |@|
a.get("password").toSuccess("Password must be supplied")
result.tupled match {
case Success((url,user,password)) => HttpConnectionParams(url,user,password)
case Failure(m) => println("There was a failure"+m)
}
这符合我的期望,但我对使用方法有疑问:
import scalaz._
某种方式对我不起作用。[1]我怎样才能从API文档中找到答案?[1]经过多次惊愕,我得到了针对应用用例的这组导入。希望这有助于某人:
import scalaz.std.string._
import scalaz.syntax.std.option._
import scalaz.syntax.apply._
import scalaz.Success
import scalaz.Failure
答案 0 :(得分:13)
通过使用.tupled
定义辅助方法并跳过.apply
步骤,您可以更好地完成此操作:
import scalaz._, Scalaz._
def lookup[K, V](m: Map[K, V], k: K, message: String): ValidationNel[String, V] =
m.get(k).toSuccess(NonEmptyList(message))
val validated: ValidationNel[String, HttpConnectionParams] = (
lookup(a, "url", "Url must be supplied") |@|
lookup(a, "username", "Username must be supplied") |@|
lookup(a, "password", "Password must be supplied")
)(HttpConnectionParams.apply)
另外,请不要羞于使用import scalaz._, Scalaz._
。我们都这样做,在绝大多数情况下它都很好。您可以随时返回并优化您的导入。我还在几年前写过this answer - 我不应该对Scalaz(或猫)有全面的了解,以便能够有效地使用它。