ValidationNel的简单验证示例

ValidationNel的简单验证示例,validation,scala,scalaz,Validation,Scala,Scalaz,这是我之前的后续行动: 假设我需要验证数据结构(例如XML、JSON、HttpRequest等)。我可以定义一个验证函数a=>ValidationNel[String,B]及其周围的包装类: class Validate[A, B](run: A => ValidationNel[String, B]) { def apply(a: A) = run(a) } 我还添加了方法,然后和以及来组合验证: def andThen[C](other: Validate[B, C]) = ne

这是我之前的后续行动:

假设我需要验证数据结构(例如XML、JSON、HttpRequest等)。我可以定义一个验证函数
a=>ValidationNel[String,B]
及其周围的包装类:

class Validate[A, B](run: A => ValidationNel[String, B]) {
  def apply(a: A) = run(a)
}
我还添加了方法
,然后
以及
来组合
验证

def andThen[C](other: Validate[B, C]) = new Validate[A, C] {a =>
  this(a) flatMap (b => other(b))
}

def andAlso(other: Validate[A, B]) = new Validate[A, B] (a =>
  (this(a), other(a)) match {
     case ((Success(b), Success(b)) => Success(b)
     case (failure @ Failure(errors), Success(b)) => failure
     case (Success(b), failure @ Failure(errors)) => failure
     case (Failure(errors1), Failure(errors2)) => Failure(errors1 + errors2)
  }
)
现在,我可以按如下方式验证数据结构:

case class Header(...)
case class Payload(...)
case class Message(header: Header, payload: Payload)

val validateHeader: Validate[Header, Header] = ...

val validatePayload: Validate[Payload, Payload] = ...

type ValidateMessage = Validate[Message, Message]

val validateMessageHeader =
  new ValidateMessage(m => validateHeader(m.header); m)

val validateMessagePayload =
  new ValidateMessage(m => validatePayload(m.payload); m)

val validateMessage = validateMessageHeader andAlso validateMessagePayload

这有意义吗?您建议如何修复/改进它?

三个注意事项:1
ValidationNel[String,A]
没有半群实例,除非
A
有,所以我不明白
中发生了什么。2.使用<代码>平面图<代码> >代码>验证<代码>是一个非常强烈的指示,您应该考虑<代码> \/<代码>。3.您的
Validate
同构于
Kleisli[({type L[x]=ValidationNel[String,x]})#L,A,B]
,当
B
有一个半群时,使用它将免费为您提供一个半群实例。感谢您的反馈!(1) 我将修正问题中的
(2)嗯(3)你是对的。我会试试看。@TravisBrown
Kleisli[M[\uz],A,B]
是一个半群,如果
M[B]
是一个半群,对吗?啊,对,我说错了,我说你只需要
B
@TravisBrown谢谢:)