Note that there are some explanatory texts on larger screens.

plurals
  1. POChaining Scalaz validation functions: Function1[A,Validation[E,B]]
    text
    copied!<p>I'm trying to write some code to make it easy to chain functions that return Scalaz <code>Validation</code> types. One method I am trying to write is analogous to <code>Validation.flatMap</code> (Short circuit that validation) which I will call <code>andPipe</code>. The other is analogous to <code>|@|</code> on <code>ApplicativeBuilder</code> (accumulating errors) except it only returns the final <code>Success</code> type, which I will call <code>andPass</code></p> <p>Suppose I have functions:</p> <pre><code>def allDigits: (String) =&gt; ValidationNEL[String, String] def maxSizeOfTen: (String) =&gt; ValidationNEL[String, String] def toInt: (String) =&gt; ValidationNEL[String, Int] </code></pre> <p>As an example, I would like to first pass the input String to both allDigits and maxSizeOf10. If there are failures, it should short circuit by not calling the toInt function and return either or both failures that occurred. If Successful, I would like to pass the Success value to the toInt function. From there, it would either Succeed with the output value being an Int, or it would fail returning only the validation failure from toInt. </p> <pre><code>def intInput: (String) =&gt; ValidationNEL[String,Int] = (allDigits andPass maxSizeOfTen) andPipe toInt </code></pre> <p>Is there a way to do this without my add-on implementation below?</p> <p>Here is my Implementation:</p> <pre><code> trait ValidationFuncPimp[E,A,B] { val f: (A) =&gt; Validation[E, B] /** If this validation passes, pass to f2, otherwise fail without accumulating. */ def andPipe[C](f2: (B) =&gt; Validation[E,C]): (A) =&gt; Validation[E,C] = (a: A) =&gt; { f(a) match { case Success(x) =&gt; f2(x) case Failure(x) =&gt; Failure(x) } } /** Run this validation and the other validation, Success only if both are successful. Fail accumulating errors. */ def andPass[D](f2: (A) =&gt; Validation[E,D])(implicit S: Semigroup[E]): (A) =&gt; Validation[E,D] = (a:A) =&gt; { (f(a), f2(a)) match { case (Success(x), Success(y)) =&gt; Success(y) case (Failure(x), Success(y)) =&gt; Failure(x) case (Success(x), Failure(y)) =&gt; Failure(y) case (Failure(x), Failure(y)) =&gt; Failure(S.append(x, y)) } } } implicit def toValidationFuncPimp[E,A,B](valFunc : (A) =&gt; Validation[E,B]): ValidationFuncPimp[E,A,B] = { new ValidationFuncPimp[E,A,B] { val f = valFunc } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload