Skip to content

Instantly share code, notes, and snippets.

@john-kurkowski
Last active December 15, 2015 13:09
Show Gist options
  • Save john-kurkowski/5265119 to your computer and use it in GitHub Desktop.
Save john-kurkowski/5265119 to your computer and use it in GitHub Desktop.
Accumulating More Than One Failure In A ValidationNEL
def evenNumber(n: Int) = if (n % 2 == 0) Some(n) else None
// an example for-comprehension …
for {
num <- List(1, 2, 3)
evenNum <- evenNumber(num)
} yield evenNum
// … which desugars to …
List(1, 2, 3) flatMap (evenNumber)
// evenNumber won't get called at all (what args could it possibly be called with?)
for {
num <- List.empty[Int] // comprehension doesn't get past this
evenNum <- evenNumber(num)
doubleEven <- evenNumber(evenNum * 2)
} yield doubleEven
val sumV: ValidationNEL[String, Int] = for {
a <- 42.successNel[String]
b <- "Boo".failNel[Int]
c <- "Wah wah".failNel[Int] // by defn of flatMap, can't get here
} yield a + b + c
// sumV == Failure(NonEmptyList(Boo))
val yes = 3.14.successNel[String]
val doh = "Error".failNel[Double]
def addTwo(x: Double, y: Double) = x + y
(yes |@| yes)(addTwo) // Success(6.28)
(no |@| no)(addTwo) // Failure(NonEmptyList(Error, Error))
// or shorthand
(yes |@| yes){_ + _} // Success(6.28)
(yes |@| doh){_ + _} // Failure(NonEmptyList(Error))
(doh |@| yes){_ + _} // Failure(NonEmptyList(Error))
(doh |@| doh){_ + _} // Failure(NonEmptyList(Error, Error))
yes >>*<< yes // Success(6.28)
yes >>*<< doh // Success(3.14)
doh >>*<< yes // Success(3.14)
doh >>*<< doh // Failure(NonEmptyList(Error, Error))
yes findSuccess yes // Success(3.14)
yes findSuccess doh // Success(3.14)
doh findSuccess yes // Success(3.14)
doh findSuccess doh // Failure(NonEmptyList(Error, Error))
yes +++ yes // Success(6.28)
yes +++ doh // Failure(NonEmptyList(Error))
doh +++ yes // Failure(NonEmptyList(Error))
doh +++ doh // Failure(NonEmptyList(Error, Error))
var sum = 0.0
val fails = collection.mutable.ArrayBuffer[String]()
yes fold (fails ++= _.list, sum += _)
doh fold (fails ++= _.list, sum += _)
if (fails.isEmpty) {
sum.successNel
} else {
NonEmptyList(fails.head, fails.tail: _*).fail
}
// Failure(NonEmptyList(Error))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment