验证字符串列表



这是我上一个问题的后续。
假设我需要编写一个validate函数,以确保给定的字符串列表由"a"、"b"和一个或多个"c"组成。

def validate(ss: List[String]): Either[NonEmptyList[MyError], Unit] = ???

假设我有三个函数来检查给定的字符串是"a"、"b"还是"c":

def validateA(str: String): Either[MyError, Unit] = ???
def validateB(str: String): Either[MyError, Unit] = ???
def validateC(str: String): Either[MyError, Unit] = ???

如何组合这些函数来实现validate

一种解决方案是"解析器组合器"方法。为类型Validator = Either[NonEmptyList[MyError], List[String]]定义一个monad实例,类似于解析器组合器等oneOrMore组合器。

我想知道是否有更简单的解决方案。

我建议你利用cats Validated

如果您真的不想更改validateT方法签名,让我们定义一些帮助程序方法:

def validateA_(str: String): ValidatedNel[MyError, Unit] = validateA(str).toValidatedNel
def validateB_(str: String): ValidatedNel[MyError, Unit] = validateB(str).toValidatedNel
def validateC_(str: String): ValidatedNel[MyError, Unit] = validateC(str).toValidatedNel

然后,您可以实现一个validate_帮助程序函数:

import cats.data.Validated.{ invalidNel, valid }
def validate_(ss: List[String]): ValidatedNel[MyError, Unit] = ss match {
  case a :: b :: c if c.nonEmpty =>
    validateA_(a) combine validateB_(b) combine c.traverseU_(validateC_)
  case _ => invalidNel(MyError(???)) //List too short
}

最后实现您的validate函数为:

def validate(ss: List[String]): Either[NonEmptyList[MyError], Unit] = 
  validate_(ss).toEither

假设:输入列表已排序,如果它短于3元素,则特定错误(例如列表太短(是可以接受的。

看起来你可以使用Scalactic,它允许人们在不缩短整个验证过程的情况下积累错误。

此示例看起来与您尝试执行的操作非常相似。看看吧!

相关内容

  • 没有找到相关文章

最新更新