Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert List[String] into ValidationNEL[String, A] in a function

I have a function with the following signature

def reject[A](errors: List[String]): ValidationNEL[String, A]

Since this is a reject method, the type A would never be returned but I need it to be reflected in order to match the signature. I was messing around with type lambdas to get my desired result as follows:

errors.map(Failure[String, A](_).liftFailNel).sequence[({type l[a] = ValidationNEL[String, a]})#l, A]

This uses the type List[A] (or appears to), rather than my desired type A. Is there a standard way to derive the result I am looking for?

like image 406
Mad Dog Avatar asked Sep 25 '12 16:09

Mad Dog


1 Answers

Because errors may be an empty List, and you are constraining yourself to have no value of type A, I don't think you can write this as a total function. To write this type signature, you would need to cheat by pretending the empty list case does not exist, e.g.

def reject[A](errors: List[String]): ValidationNEL[String, A] =
  Failure(errors.toNel.get) // bad!

Edit: As Apocalisp pointed out, you can of course make this a total function, by introducing an error for the empty list. But I would only do that if errors is computed at runtime, and I suspect this is not your use case, as it would lead to silly errors such as:

def reject[A](errors: List[String]): ValidationNEL[String, A] =
  Failure(errors.toNel getOrElse NonEmptyList("Error: There were no errors!"))

Why not pass the errors as a NonEmptyList instead - presumably you only use this function if you have errors to use at compile time.

def reject[A](errors: NonEmptyList[String]): ValidationNEL[String, A] =
  Failure(errors)

You can make this terser to use by copying the signature of NonEmptyList.apply (and specialising it to String):

def reject[A](h: String, t: String*): ValidationNEL[String, A] =
  Failure(NonEmptyList(h, t: _*))

Let's try it out:

scala> reject("foo", "bar", "baz")
res0: scalaz.package.ValidationNEL[String,Nothing] = Failure(NonEmptyList(foo, bar, baz))
like image 183
Ben James Avatar answered Nov 06 '22 10:11

Ben James