Scalaz Validation with applicative functor |#| not working - validation

I'm trying to use Scalaz 7 Validation in my app. However, I'm having an issue getting the |#| applicative functor to coalesce my failures. Here's the code I 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 and sizeValidate functions just return ValidationResults.
The problem is, this code won't compile. The error message is:
Type mismatch, expected F0.type#M[NotInferedB], actual: ValidationResult
I have no idea what that means... do I need to give Scala more type info?
What I'm trying to accomplish is, if all fields are successNels, then return that, otherwise, return a combination of all the failureNels.
Has |#| changed since previous version of Scalaz? Because even if I do something like:
().successNel |#| ().successNel
I get the same error.
Update
I started poking around the Scalaz source and I found the +++ which seems to do what I want.
What's the difference between +++ and |#|?

Scalaz's applicative builder syntax (|#|) gives you a way of "lifting" functions into an applicative functor. Suppose we have the following results, for 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 the list concatenation function (++) into the Validation like 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 is a little weird—it's very unlike how you lift functions into an applicative functor in Haskell, for example, and is designed this way primarily to outsmart Scala's fairly stupid type inference system. See my answer here or blog post here for more discussion.
One part of the weirdness is that xs |#| ys doesn't really mean anything on its own—it's essentially an argument list that's waiting to be applied to a function that it will lift into its applicative functor and apply to itself.
The +++ on Validation is a much simpler kind of creature—it's just the addition operation for the Semigroup instance for the type (note that you could equivalently use Scalaz's semigroup operator |+| here in place of +++). You give it two Validation results with matching semigroup types and it gives you another Validation—not some awful ApplyOps thing.
As a side note, in this case the addition operation for Validation's semigroup is the same as the semigroup operation for the right side lifted into the Validation:
scala> (xs |+| ys) == (xs |#| ys)(_ |+| _)
res3: Boolean = true
This won't always be the case, however (it's not for \/, for example, where the semigroup accumulates errors but the applicative functor doesn't).

Related

Scala Tree/Graph Implementation

I have a problem about a "customer invitation" where a person can invite another person and the invitation is only valid if the invited person invitee someone.
To solve this problem, i was thinking to write a Tree algorithm instead a Graph algorithm.
I'm trying to write this tree structure in Scala and here is how i've started:
case class MyNode(key:Int, children:Option[List[MyNode]] = None)
class MyNodeManager {
def find(key: Int, tree: Option[List[MyNode]]) = tree match {
case None => None
case (h :: t) =>
println("aa")
/*if(h.key == key)
Option(h)
else
find(h ::: t)
*/
}
}
The input will be something like:
val invites = List((1, 2), (1, 3), (3, 6))
I would like to work with Option[List[MyNode]] because children are option and if the node has been invited, i would like to set value an empty list instead None.
Tree is the best structure to solve my problem or should i go to Graph or something like that (a node in a graph can have multiple children?)? And the other question..what's the difference on those lines (h :: t) and (h ::: t)?
The following code has a compile error:
Error:(16, 13) constructor cannot be instantiated to expected type;
found : scala.collection.immutable.::[B]
required: Option[List[MyNode]]
case (h :: t) =>
^
How can i work with Option[List]?
Should be
def find(key: Int, tree: Option[List[MyNode]]) = tree match {
case None => None
case Some(h :: t) =>
println("aa")
/*if(h.key == key)
Option(h)
else
find(h ::: t)
*/}
You are match Option object not tuple.
This match is not exhaustive because you are missing
case Some(Nil) => ....
I find it will be better to use only list without Optional. This is mostly about semantic. Optional means something is empty. We have value for empty list (Nil) so we don't need to use additional object to mark such situation. Empty list should be enough
::: function adds the elements of a given list in front of your list. Simply this function is used to concatenate two list
:: is function which add element at the begging of the list.
Also in Scala :: is a case class which have head and tail. If you want to know more about List implementation I suggest you to read https://www.amazon.com/Functional-Programming-Scala-Paul-Chiusano/dp/1617290653

How to implement simple validation in Scala

Suppose I need to validate request parameters. The validation result is either Success or Failure with NonEmptyList[String]. I can probably use ValidationNel[String, Unit] but it seems a bit overkill. I guess I need a simpler abstraction (see below).
trait ValidationResult
object Success extends ValidationResult
class Failure(errors: NonEmptyList[String]) extends ValidationResult
and a binary operation andAlso to combine two results:
trait ValidationResult {
def andAlso(other: ValidationResult): ValidationResult =
(this, other) match {
case (Success, Success) => Success
case (Success, failure # Failure(_)) => failure
case (failure # Failure(_), Success) => failure
case (Failure(errors1), Failure(errors2)) => Failure(errors1 + errors2)
}
}
Now if I validate three parameters with functions checkA, checkB, and checkC I can easily compose them as follows:
def checkA(a: A): ValidationResult = ...
def checkB(b: B): ValidationResult = ...
def checkC(c: C): ValidationResult = ...
def checkABC(a: A, b: B, c: C) = checkA(a) andAlso checkB(b) andAlso checkC(c)
Does it make sense ?
Does this abstraction have a name ? Maybe a Monoid ?
Is it implemented in scalaz or any other scala library ?
It is indeed a Monoid, and you can be much more precise : it is a List[String] (up to an isomporphism). ValidationResult is indeed isomorphic to a List[String], with Success for Nil, and andAlso is concatenation ::: / ++.
This makes sense, a ValidationResult is a list of errors, and when there are none, that means success.
However, as you note right at the beginning, it all amounts to using ValidationNel[String, Unit], where Unit, "no data of interest" is the interesting part. If means you will handle the actual data separately. You may win a little bit here, and that little bit is avoiding the syntax of Applicative, sprinkling your code with |#| and suchlike; also, a not-often mentioned price of Monads and Co, making it easier to work with a debugger. But there is a downside, as your code grows with places where errors may occur multiplying too, managing the flow by hand will quickly become painful and I would not go that way.
The usual alternative is exceptions.

Processing a list of Scalaz6 Validation

Is there an idiomatic way to handle a collection of Validation in Scalaz6?
val results:Seq[Validation[A,B]]
val exceptions = results.collect{case Failure(exception)=>exception}
exceptions.foreach{logger.error("Error when starting up ccxy gottware",_)}
val success = results.collect{case Success(data)=>data}
success.foreach {data => data.push}
if (exceptions.isEmpty)
containers.foreach( _.start())
I could think of using a fold when looping on results, but what about the final test?
The usual way to work with a list of validations is to use sequence to turn the list into a Validation[A, List[B]], which will be be empty (i.e., a Failure) if there were any errors along the way.
Sequencing a Validation accumulates errors (as opposed to Either, which fails immediately) in the semigroup of the left-hand type. This is why you often see ValidationNEL (where the NEL stands for NonEmptyList) used instead of simply Validation. So for example if you have this result type:
import scalaz._, Scalaz._
type ExceptionsOr[A] = ValidationNEL[Exception, A]
And some results:
val results: Seq[ExceptionsOr[Int]] = Seq(
"13".parseInt.liftFailNel, "42".parseInt.liftFailNel
)
Sequencing will give you the following:
scala> results.sequence
res0: ExceptionsOr[Seq[Int]] = Success(List(13, 42))
If we had some errors like this, on the other hand:
val results: Seq[ExceptionsOr[Int]] = Seq(
"13".parseInt.liftFailNel, "a".parseInt.liftFailNel, "b".parseInt.liftFailNel
)
We'd end up with a Failure (note that I've reformatted the output to make it legible here):
scala> results.sequence
res1: ExceptionsOr[Seq[Int]] = Failure(
NonEmptyList(
java.lang.NumberFormatException: For input string: "a",
java.lang.NumberFormatException: For input string: "b"
)
)
So in your case you'd write something like this:
val results: Seq[ValidationNEL[A, B]]
results.sequence match {
case Success(xs) => xs.foreach(_.push); containers.foreach(_.start())
case Failure(exceptions) => exceptions.foreach(
logger.error("Error when starting up ccxy gottware", _)
)
}
See my answers here and here for more detail about sequence and about Validation more generally.

Scalaz Validation, validate inner value

I have a Validation object
val v = Validation[String, Option[Int]]
I need to make a second validation, to check if actual Integer value is equals to 100 for example. If I do
val vv = v.map(_.map(intValue => if (intValue == 100)
intValue.success[String]
else
"Bad value found".fail[Integer]))
I get:
Validation[String, Option[Validation[String, Int]]]
How is it possible to get vv also as Validation[String, Option[Int]] in most concise way
=========
Found possible solution from my own:
val validation: Validation[String, Option[Int]] = Some(100).success[String]
val validatedTwice: Validation[String, Option[Int]] = validation.fold(
_ => validation, // if Failure then return it
_.map(validateValue _) getOrElse validation // validate Successful result
)
def validateValue(value: Int): Validation[String, Option[Int]] = {
if (value == 100)
Some(value).success[String]
else
"Bad value".fail[Option[Int]]
}
Looks not concise and elegant although it works
==============
Second solution from my own, but also looks over-compicated:
val validatedTwice2: Validation[String, Option[Int]] = validation.flatMap(
_.map(validateValue _).map(_.map(Some(_))) getOrElse validation)
def validateValue(value: Int): Validation[String, Int] = {
if (value == 100)
value.success[String]
else
"Bad value".fail[Int]
}
Your solution is over-complicated. The following will suffice!
v flatMap (_.filter(_ == 100).toSuccess("Bad value found"))
The toSuccess comes from OptionW and converts an Option[A] into a Validation[X, A] taking the value provided for the failure case in the event that the option is empty. The flatMap works like this:
Validation[X, A]
=> (A => Validation[X, B])
=> (via flatMap) Validation[X, B]
That is, flatMap maps and then flattens (join in scalaz-parlance):
Validation[X, A]
=> (A => Validation[X, B]]
=> (via map) Validation[X, Validation[X, B]]
=> (via join) Validation[X, B]
First, let's set up some type aliases because typing this out repeatedly will get old pretty fast. We'll tidy up your validation logic a little too while we're here.
type V[X] = Validation[String, X]
type O[X] = Option[X]
def checkInt(i: Int): V[Int] = Validation.fromEither(i != 100 either "Bad value found" or i)
val v: V[O[Int]] = _
this is where we're starting out - b1 is equivalent to your vv situation
val b1: V[O[V[Int]]] = v.map(_.map(checkInt))
so let's sequence the option to flip over the V[O[V[Int]]] into a V[V[O[Int]]]
val b2: V[V[O[Int]]] = v.map(_.map(checkInt)).map(_.sequence[V, Int])
or if you're feeling lambda-y it could have been
sequence[({type l[x] = Validation[String, x]})#l, Int]
next we flatten out that nested validation - we're going to pull in the Validation monad because we actually do want the fastfail behaviour here, although it's generally not the right thing to do.
implicit val monad = Validation.validationMonad[String]
val b3: V[O[Int]] = v.map(_.map(checkInt)).map(_.sequence[V, Int]).join
So now we've got a Validation[String, Option[Int]], so we're there, but this is still pretty messy. Lets use some equational reasoning to tidy it up
By the second functor law we know that:
X.map(_.f).map(_.g) = X.map(_.f.g) =>
val i1: V[O[Int]] = v.map(_.map(checkInt).sequence[V, Int]).join
and by the definition of a monad:
X.map(f).join = X.flatMap(f) =>
val i2: V[O[Int]] = v.flatMap(_.map(checkInt).sequence[V, Int])
and then we apply the free theorem of traversal:
(I struggled with that bloody paper so much, but it looks like some of it sunk in!):
X.map(f).sequence = X.traverse(f andThen identity) = X.traverse(f) =>
val i3: V[O[Int]] = v.flatMap(_.traverse[V, Int](checkInt))
so now we're looking at something a bit more civilised. I imagine there's some trickery to be played with the flatMap and traverse, but I've run out of inspiration.
Use flatMap, like so:
v.flatMap(_.parseInt.fail.map(_.getMessage).validation)

How to sort the list by its accountID using quick sort in Haskell

Im a student who is really new to functional programming. Im working on a banking application where the data has been already defined as,
type Accountno = Int
data Accounttype = Saving | Current | FixedDeposit deriving (Show,Read)
type Accountamount = Int
type Name = String
type Account = (Accountno, Name, Accounttype, Accountamount)
exampleBase :: [Account]
exampleBase = [ (1,"Jennifer",Saving,1000 ) ,
(5,"Melissa",Current,3000) ,
(2,"Alex",Saving,1500)]
Im trying to sort the list by its account number using the following code,
sortByID :: (Ord a) => [a] -> [a]
sortByID [] = []
sortByID (l :ls) =
let
smallerSorted = sortByID [x | x <- ls, x <= l]
biggerSorted = sortByID [x | x <- ls, x > l]
in
smallerSorted ++ [l] ++ biggerSorted
viewSortedDetails :: IO()
viewSortedDetails =
do
putStrLn "Account Details Sorted By Account ID"
let records = sortByID exampleBase
let viewRecord = map show records
mapM_ putStrLn viewRecord
But I do not get the expected result. as it gives me an error, informing "Instance of Ord Accounttype required for definition of viewSortedDetails".Please can some one help me to overcome this problem
Thanks a lot!
Well, the problem is that you're using ordering comparisons, such as <=, on two Account values, which would require Account to be an instance of Ord. Now, Account is a synonym for a four-element tuple, which are defined to be instances of Ord when all the types in the tuple are. Accountno, Name, and Accountamount are all synonyms for types with Ord instances, but Accounttype is not.
You could make it possible to sort Account values directly by making Accounttype an instance of Ord, which you can do by simply adding it to the deriving clause.
However, if you want to specifically sort only by the account number, not the other elements of the tuple, you'll need to do something differently. One option would be to make Account a data type with a custom Ord instance:
data Account = Account Accountno Name Accounttype Accountamount deriving (Eq, Show, Read)
instance Ord Account where
(...)
Then you can define the ordering however you like.
Alternatively, you can leave it as is and instead only compare the element you want instead of the entire Account value, using something like this:
accountNo :: Account -> Accountno
accountNo (n,_,_,_) = n
...and then doing the comparison with something like smallerSorted = sortByID [x | x <- ls, accountNo x <= accountNo l]. The standard libraries also include a function on for this purpose, but it would awkward to use in this case.
A few other remarks, which are less relevant to your question, on the general subject of Haskell code:
Defining Account as a data type, probably using the record syntax, would be nicer than using a type synonym here. Large tuples can be awkward to work with.
Accountno and Accountamount should probably be different types as well, to avoid mixing them with other Ints: the first because doing arithmetic on account numbers makes little sense, the latter in part because (I'm guessing) you're implicitly using fixed point arithmetic, such that 100 actually means 1.00, and in general just to avoid confusion.
In fact, Int is probably a bad choice for Accountamount anyway: Why not something from Data.Fixed, Ratio Integer, or a base-10-safe floating point type (although there isn't one in the standard libraries, unfortunately).
The standard libraries of course include sorting functions already--I'm assuming the reimplementation is for learning purposes, but in practice it could all be replaced by something like sortBy (compare `on` accountNo).

Resources