问题描述
假设我想在 Scala 中编写以下逻辑
val xdir = System.getProperty("XDir")如果(xdir == null)error("No XDir")//记录错误并退出val ydir = System.getProperty("YDir")如果(ydir == null)错误(没有YDir")if (!new File(xdir).isDirectory)error("XDir 不是目录")if (!new File(ydir).isDirectory)error("YDir 不是目录")if (!new File(xdir).exists)错误(XDir 不存在")if (!new File(ydir).exists)错误(YDir 不存在")...(等等)在 Scala 中编写此验证链的最佳方法是什么?
这里有一些有用的东西:
def sysValue(prop: String) = Option(System.getProperty(prop))//返回Option[String]def trySysValue(prop: String) =//返回Either[String, String]sysValue(prop) map Right getOrElse Left("Absent property:" + prop)
然后你可以通过它的右投影
使用Either
的一元组合val batch =//批处理是Either[String, (File, File)]为了 {x <- trySysValue("XDir")).rightxf <- dir(x).righty <- trySysValue("YDir").rightyf
地点:
def dir(s: String) = {//返回Either[String, File]val f = 新文件if (!f.exists()) Left("不存在:" + f)else if (!f.isDir()) Left("不是目录:" + f)否则正确(f)}
Either
的左侧将是一条错误消息.这种 monadic 组合快速失败.您可以使用 scalaz 实现将累积所有失败的组合(例如,如果 XDir
和 YDir
都不存在,您将看到这两条消息)代码>验证代码>.在这种情况下,代码将如下所示:
def trySysValue(prop: String) =//返回验证[String, String]sysValue(prop) map Success getOrElse ("Absent property:" + prop).faildef dir(s: String) = {val f = 新文件if (!f.exists())("不存在:" + f).failelse if (!f.isDir()) ("不是目录:" + f).fail否则 f. 成功}val batch =//batch is ValidationNEL[String, (File, File)](trySysValue("XDir")) flatMap dir).liftFailNel <|*|>(trySysValue("YDir")) flatMap dir).liftFailNel
Suppose I would like to code the following logic in Scala
val xdir = System.getProperty("XDir") if (xdir == null) error("No XDir") // log the error and exit val ydir = System.getProperty("YDir") if (ydir == null) error("No YDir") if (!new File(xdir).isDirectory) error("XDir is not a directory") if (!new File(ydir).isDirectory) error("YDir is not a directory") if (!new File(xdir).exists) error("XDir does not exis") if (!new File(ydir).exists) error("YDir does not exist") ... (and so on)
What is the best way to code this chain of validations in Scala?
Here's some useful things:
def sysValue(prop: String) = Option(System.getProperty(prop)) //returns Option[String]
def trySysValue(prop: String) = //returns Either[String, String]
sysValue(prop) map Right getOrElse Left("Absent property: " + prop)
Then you can use monadic composition of Either
through its right-projection
val batch = //batch is Either[String, (File, File)]
for {
x <- trySysValue("XDir")).right
xf <- dir(x).right
y <- trySysValue("YDir").right
yf <- dir(y).right
}
yield (xf, yf)
Where:
def dir(s: String) = { //returns Either[String, File]
val f = new File(s)
if (!f.exists()) Left("Does not exist: " + f)
else if (!f.isDir()) Left("Is not a directory: " + f)
else Right(f)
}
The left-hand-side of the Either
will be an error message. This monadic composition is fail fast. You can achieve composition which will accumulate all failures (for example, if neither XDir
nor YDir
exist, you would see both messages) using scalaz Validation
. In that case, the code would look like this:
def trySysValue(prop: String) = //returns Validation[String, String]
sysValue(prop) map Success getOrElse ("Absent property: " + prop).fail
def dir(s: String) = {
val f = new File(s)
if (!f.exists())("Does not exist: " + f).fail
else if (!f.isDir()) ("Is not a directory: " + f).fail
else f.success
}
val batch = //batch is ValidationNEL[String, (File, File)]
(trySysValue("XDir")) flatMap dir).liftFailNel <|*|> (trySysValue("YDir")) flatMap dir).liftFailNel
这篇关于如何在 Scala 中编写此验证逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!