我有Map[String,String]配置值.我想提取一系列密钥,并提供有意义的错误消息,如果缺少任何密钥.例如:
val a = Map("url"->"http://example.com", "user"->"bob", "password"->"12345")
Run Code Online (Sandbox Code Playgroud)
假设我想将其转换为案例类:
case class HttpConnectionParams(url:String, user:String, password: String)
Run Code Online (Sandbox Code Playgroud)
现在,我可以简单地使用for循环来提取值:
for(url <- a.get("url");
user <- a.get("user");
password <- a.get("password")) yield {
HttpConnectionParams(url,user,password)
}
Run Code Online (Sandbox Code Playgroud)
得到一个Option[HttpConnectionParams].这很干净,除非我得到一个None然后我不知道缺少什么.我想提供这些信息.
输入scalaz.我使用的是7.1.3版本.
从我能够组合起来(这里有一个很好的参考)我可以使用析取:
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)
}
Run Code Online (Sandbox Code Playgroud)
这很好,因为现在我收到一条错误信息,但这是铁路导向的,因为它在第一次失败时停止.如果我想获得所有错误怎么办?让我们使用验证和applicative builder(又名"| @ |"):
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)
}
Run Code Online (Sandbox Code Playgroud)
这符合我的期望,但我对使用方法有一些疑问:
import scalaz._不知何故对我不起作用.[1] 我怎样才能从API文档中找到答案?[1]经过多次惊愕,我得到了针对应用用例的这组导入.希望这有助于某人:
import scalaz.std.string._
import scalaz.syntax.std.option._
import scalaz.syntax.apply._
import scalaz.Success
import scalaz.Failure
Run Code Online (Sandbox Code Playgroud)
Tra*_*own 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)
Run Code Online (Sandbox Code Playgroud)
另外,请不要羞于使用import scalaz._, Scalaz._.我们都这样做,在绝大多数情况下都很好.您可以随时返回并优化您的导入.我还坚持多年前写的这个答案 - 你不应该觉得你需要全面了解Scalaz(或猫)才能有效地使用它.