0

Suppose I need to validate an input XML, e.g.

<a>
  <a1>a1a1a1</a1>
  <a2>a2a2a2</a2>
  <a3/>
</a>

I need to make sure that its root element has label "a" and children with labels "a1", "a2", "a3" and texts "a1a1a1", "a2a2a2" and "" respectively.

I can define the basic validation functions as follows:

type Status = ... // either Ok or list of error messages
type Validate[A] = A => Status
type ValidateNode = Validate[scala.xml.Node]

val label(l: String): ValidateNode = ... // trivial
val text(t: String): ValidateNode =  ... // trivial
val child(vn: ValidateNode) = ... // find such a child "c" that "vn(c)" is Ok

Since Status is a monoid (isomorphic to list) then Validate[A] is a monoid too and we can compose the validation functions with |+|

val a1: ValidateNode = label("a1") |+| text("a1a1a1")
val a2: ValidateNode = label("a2") |+| text("a2a2a2") 
val a3: ValidateNode = label("a3")
val a:  ValidateNode = label("a") |+| child(a1) |+| child(a2) |+| child(a3) 

Does it make sense ? How would you fix/improve it ?

Michael
  • 41,026
  • 70
  • 193
  • 341
  • This looks reasonable, but if you're using Scalaz (?) is there a reason you wouldn't just go with `ValidationNel`? – Travis Brown Jun 12 '15 at 16:01
  • I thought about `ValidationNel[String, Unit]` but it _felt_ like an overkill. What I _really_ need is just a list, isn't it ? – Michael Jun 12 '15 at 16:18
  • Yeah, `ValidationNel[String, Unit]` is isomorphic to `List[String]`, but the former is much clearer about your intent (and some of the combinators on `Validation` could be useful, depending on what you're doing). – Travis Brown Jun 12 '15 at 16:22
  • Well ... maybe I should re-consider `ValidationNel`. Thank you for the input. – Michael Jun 12 '15 at 16:25

0 Answers0