scala - Scalaz Validation with applicative functor |@| not working -


i'm trying use scalaz 7 validation in app. however, i'm having issue getting |@| applicative functor coalesce failures. here's code have:

type validationresult = validationnel[string, unit]  def validate[a: classtag](instance: a, fieldnames: option[seq[string]] = none): validationresult = {     val fields = classtag[a].runtimeclass.getdeclaredfields     val fieldsubset = fieldnames match {         case some(names) => fields.filter { field => names.contains(field.getname) }         case none => fields     }     fieldsubset.map {         field => field.getannotations.toseq.map {             field.setaccessible(true)             val (name, value) = (field.getname, field.get(instance))             field.setaccessible(false)             annotation => annotation match {                 case min: min => minvalidate(name, value, min.value())                 case size: size => sizevalidate(name, value, size.min(), size.max())             }         }     }.flatten[validationresult].foldleft(().successnel[string])(_ |@| _) } 

the minvalidate , sizevalidate functions return validationresults.

the problem is, code won't compile. error message is:

type mismatch, expected f0.type#m[notinferedb], actual: validationresult 

i have no idea means... need give scala more type info?

what i'm trying accomplish is, if fields successnels, return that, otherwise, return combination of failurenels.

has |@| changed since previous version of scalaz? because if like:

().successnel |@| ().successnel 

i same error.

update

i started poking around scalaz source , found +++ seems want.

what's difference between +++ , |@|?

scalaz's applicative builder syntax (|@|) gives way of "lifting" functions applicative functor. suppose have following results, example:

val xs: validationnel[string, list[int]] = "error!".failnel val ys: validationnel[string, list[int]] = list(1, 2, 3).success val zs: validationnel[string, list[int]] = list(4, 5).success 

we can lift list concatenation function (++) validation this:

scala> println((ys |@| zs)(_ ++ _)) success(list(1, 2, 3, 4, 5))  scala> println((xs |@| ys)(_ ++ _)) failure(nonemptylist(error!))  scala> println((xs |@| xs)(_ ++ _)) failure(nonemptylist(error!, error!)) 

this syntax little weird—it's unlike how lift functions applicative functor in haskell, example, , designed way outsmart scala's stupid type inference system. see my answer here or blog post here more discussion.

one part of weirdness xs |@| ys doesn't mean on own—it's argument list that's waiting applied function lift applicative functor , apply itself.

the +++ on validation simpler kind of creature—it's addition operation semigroup instance type (note equivalently use scalaz's semigroup operator |+| here in place of +++). give 2 validation results matching semigroup types , gives validation—not awful applyops thing.


as side note, in case addition operation validation's semigroup same semigroup operation right side lifted validation:

scala> (xs |+| ys) == (xs |@| ys)(_ |+| _) res3: boolean = true 

this won't case, (it's not \/, example, semigroup accumulates errors applicative functor doesn't).


Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -