Как проверить XML с помощью моноида в Scala?

Предположим, мне нужно проверить входной XML, например.

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

Мне нужно убедиться, что его корневой элемент имеет метку "a" и дочерние элементы с метками "a1", "a2", "a3" и текстами "a1a1a1", "a2a2a2" и "" соответственно.

Я могу определить основные функции проверки следующим образом:

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

Поскольку Status является моноидом (изоморфным списку), то Validate[A] также является моноидом, и мы можем составить функции проверки с помощью |+|

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) 

Имеет ли это смысл ? Как бы вы это исправили/улучшили?


person Michael    schedule 12.06.2015    source источник
comment
Это выглядит разумно, но если вы используете Scalaz (?), есть ли причина, по которой вы не можете просто использовать ValidationNel?   -  person Travis Brown    schedule 12.06.2015
comment
Я думал о ValidationNel[String, Unit], но почувствовал, что это излишество. Мне на самом деле нужен только список, не так ли?   -  person Michael    schedule 12.06.2015
comment
Да, ValidationNel[String, Unit] изоморфен List[String], но первый гораздо яснее описывает ваши намерения (и некоторые комбинаторы в Validation могут быть полезны, в зависимости от того, что вы делаете).   -  person Travis Brown    schedule 12.06.2015
comment
Ну... может быть, мне следует пересмотреть ValidationNel. Благодарим вас за вклад.   -  person Michael    schedule 12.06.2015