假设我想在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)
在Scala中编写此验证链的最佳方法是什么?
这里有一些有用的东西:
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)
Run Code Online (Sandbox Code Playgroud)
Either然后你可以通过它的右投影使用一元组合
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)
Run Code Online (Sandbox Code Playgroud)
在哪里:
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)
}
Run Code Online (Sandbox Code Playgroud)
的左侧Either将是错误消息。这种一元组合很快就会失败。您可以使用scalaz实现组合,它将累积所有失败(例如,如果两者都不XDir存在YDir,您将看到两条消息)。在这种情况下,代码将如下所示: Validation
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
562 次 |
| 最近记录: |