如何在 Scala 中编写此验证逻辑? [英] How to code this validation logic in Scala?

查看:35
本文介绍了如何在 Scala 中编写此验证逻辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我想在 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 <- dir(y).right}产量 (xf, yf)

地点:

def dir(s: String) = {//返回Either[String, File]val f = 新文件if (!f.exists()) Left("不存在:" + f)else if (!f.isDir()) Left("不是目录:" + f)否则正确(f)}

Either 的左侧将是一条错误消息.这种 monadic 组合快速失败.您可以使用 scalaz 实现将累积所有失败的组合(例如,如果 XDirYDir 都不存在,您将看到这两条消息)代码>验证.在这种情况下,代码将如下所示:

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 中编写此验证逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆