这是对我之前http://candycode.io/how-to-set-up-different-auto-layout-constraints-for-different-screen-sizes/的跟进
假设我需要编写一个函数def method_here
# Other method stuff
repsond_to do |format|
format.js
end
end
,以确保给定的字符串列表包含" a"," b",以及一个或多个" ; C"
validate
假设我有三个函数来检查给定的字符串是" a"," b"还是" c":
def validate(ss: List[String]): Either[NonEmptyList[MyError], Unit] = ???
如何编写这些函数来实现def validateA(str: String): Either[MyError, Unit] = ???
def validateB(str: String): Either[MyError, Unit] = ???
def validateC(str: String): Either[MyError, Unit] = ???
?
一种解决方案是"解析器组合器"做法。为类型validate
定义monad实例,像Validator = Either[NonEmptyList[MyError], List[String]]
这样的组合器类似于解析器组合器等。
我想知道是否有更简单的解决方案。
答案 0 :(得分:3)
我建议您利用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
个元素,则可以接受特定错误(例如列表太短)。
答案 1 :(得分:2)