Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scalaz中使用|@进行验证 背景_Scala_Scalaz - Fatal编程技术网

在Scalaz中使用|@进行验证 背景

在Scalaz中使用|@进行验证 背景,scala,scalaz,Scala,Scalaz,我有配置值的映射[String,String]。我想提取一系列键,并在其中任何一个键丢失时提供有意义的错误消息。例如: val a = Map("url"->"http://example.com", "user"->"bob", "password"->"12345") 假设我想将其转换为案例类: case class HttpConnectionParams(url:String, user:String, password: String) 现在,我可以简单地使用fo

我有配置值的
映射[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) 
}
这很好,因为现在我收到一条错误消息,但这是因为它在第一次失败时停止。如果我想得到所有的错误怎么办?让我们使用验证和应用程序生成器(也称为“|@|”):

问题 这正是我所期望的,但我对其用法有一些疑问:

  • 对于这个用例,scalaz是否有一个易于使用的替代品?如果不需要的话,我不想打开潘多拉的盒子,介绍斯卡拉

  • 我不想使用scalaz的一个原因是,如果您像我一样不了解整个框架,那么很难弄清楚该怎么做。例如,要使上述代码正常工作,您需要的隐式列表是什么<代码>导入scalaz.\u不知何故对我不起作用。[1]如何从API文档中找出这一点
  • 是否有更简洁的方式来表达验证用例?我跌跌撞撞地走了过去,直到我找到了一些行之有效的方法,我不知道在scalaz是否还有其他更好的方法来做同样的事情
[1] 在经历了许多惊愕之后,我找到了这组应用程序用例的导入。希望这对某人有所帮助:

import scalaz.std.string._
import scalaz.syntax.std.option._
import scalaz.syntax.apply._
import scalaz.Success
import scalaz.Failure

通过定义一个helper方法并使用
.apply>跳过
.tuple
步骤,您可以更好地实现这一点:

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.\uu,scalaz.\u
。我们都这样做,而且在绝大多数情况下都很好。您可以随时返回并在以后优化导入。我仍然支持我几年前写的文章,你不应该觉得你需要对Scalaz(或CAT)有一个全面的了解才能有效地使用它。

“我不想使用Scalaz的一个原因是,如果你像我一样不了解整个框架,你真的很难想出该怎么办。”-我不会直接对托尼·莫里斯说;)。Scalaz可能不是每个人都喜欢的茶;如果你不具备核心的FP说服力和/或不熟悉Haskell(这需要从该语言中获得很多灵感),那么理解它需要一个陡峭的学习曲线。这是一个强大的图书馆,如果你知道如何使用它的话——我感觉你在敲它,因为你不想费心去完整地学习它——这不是Scalaz的错——Scalaz的替代品是猫。它的目标之一是在文档和示例方面比Scalaz更加开放和用户友好,尽管我发现Scalaz社区已经准备好帮助解决我遇到的任何问题。是的,一位同事推荐了CAT,但在版本0.2中,人们是否已经准备好普遍使用它了?另外,如果这篇文章的内容是尖刻的,向任何scalaz的支持者道歉。我真的很想喜欢它。我看到了力量。只是刚开始是令人沮丧的。如果人们还有其他的建议,我想听听。我真的很想知道是否有一种更简单的方法来找出我想要弄明白的东西。我之所以创建它是因为我不想打开通往scalaz的大门,只是验证部分刚刚注意到这并不是你第一个问题的答案,但目前还没有正确的答案,在标准库中积累析取类型时出错,因此除非您想自己使用,否则最好选择cats或Scalaz(或Scalactic)。您回答了我没有问的一个问题,即使用非空列表类(ValidationNel等)。这是为了避免后续任何人将多条错误消息简单地串联在一起。谢谢,这很有帮助。
import scalaz.std.string._
import scalaz.syntax.std.option._
import scalaz.syntax.apply._
import scalaz.Success
import scalaz.Failure
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)