使用| @ |进行验证在斯卡拉兹
背景
我有配置值的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) } 获取选项[HttpConnectionParams].这很干净,除非我得到一个无,然后我不知道缺少什么.我想提供这些信息. 使用Scalaz验证 输入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,password) } 这很好,因为现在我收到一条错误消息,但这是railway oriented,因为它在第一次失败时停止.如果我想获得所有错误怎么办?让我们使用验证和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,password)) => HttpConnectionParams(url,password) case Failure(m) => println("There was a failure"+m) } 问题 这符合我的期望,但我对使用方法有一些疑问: >对于这个用例,是否有一个易于使用的替代scalaz?如果我不需要,我宁愿不打开潘多拉的盒子并引入scalaz. [1]经过多次惊愕,我得到了针对应用用例的这组导入.希望这有助于某人: import scalaz.std.string._ import scalaz.syntax.std.option._ import scalaz.syntax.apply._ import scalaz.Success import scalaz.Failure 解决方法
你可以通过定义一个帮助器方法并使用.apply跳过.tupled步骤来更好地完成这个:
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(或猫),以便能够有效地使用它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |