1

I think I understand what sequence is. I am wondering why it does not work with List[ValidationNel]. For instance:

The sequence works fine with List[Option]]

scala> val os = List(1.some, 2.some)
os: List[Option[Int]] = List(Some(1), Some(2))

scala> os.sequence
res10: Option[List[Int]] = Some(List(1, 2))

... but does not work with List[ValidationNel]

scala> val vs: List[ValidationNel[String, Int]] = List(Success(1), Success(2))
vs: List[scalaz.ValidationNel[String,Int]] = List(Success(1), Success(2))

scala> vs.sequence
<console>:15: error: could not find implicit value for parameter ev:scalaz.Leibniz.===[scalaz.ValidationNel[String,Int],G[B]]

... however sequenceU does work with List[ValidationNel]

scala> vs.sequenceU
res14: scalaz.Validation[scalaz.NonEmptyList[String],List[Int]] = Success(List(1, 2))

My questions are: Why does not sequence work with List[ValidationNel] ? Why does sequenceU work with it ?

Michael
  • 41,026
  • 70
  • 193
  • 341

2 Answers2

9

.sequenceU uses the Unapply technique to derive the correct types, where as for .sequence you need to manually provide the types for it.

To make things a bit more annoying, the first type argument of sequence needs a type parameter that takes one type parameter not two like ValidationNel. So you either type lambda it, or do a local type definition.

Try

type X = ValidationNel[String,X]

vs.sequence[X, Int]

or

vs.sequence[({type l[A]=ValidationNel[String,A]})#l,Int]
melps
  • 1,247
  • 8
  • 13
  • Great ! Thank you for the explanation. One more question: why does `sequence` work with `List[Option]` w/o any type parameter ? – Michael Jun 24 '15 at 08:18
  • I'm not certain, but I guess List[Option] can be easily destructured into the correct type shapes (i.e. without the need for type lambdas) so the type system can figure out what it's supposed to do. – melps Jun 24 '15 at 08:22
  • I find that more often than not, .sequence needs type parameters to work. – melps Jun 24 '15 at 08:23
  • 2
    `Option` is a 1-parameter type. The compiler knows that `sequence` requires a type parameter `G[_]`. It can infer that for `Option[String]` `G` is `Option`, but for `ValidationNel[String, Int]` it doesn't know what `G` is. – lmm Jun 24 '15 at 13:06
  • @lmm Thanks. So the problem is the number of type parameters. I see it now. – Michael Jun 24 '15 at 13:07
  • is it valid to use `X` in such a circular way ? ```type X = ValidationNel[String,X]``` – rloth Feb 06 '18 at 14:27
0

Not an expert on Scalaz.

To be short, because ValidationNel is not monad, so this conversion is not valid:

List[ValidationNel[SomeType]] => ValidationNel[List[SomeType]]

as the error message shows: implicit value not found, which indicates no such conversion.

digit plumber
  • 1,140
  • 2
  • 14
  • 27
  • I am afraid it is not true. Monads are _not_ commutative. Applicatives (those that aren't monads) -- are. – Michael Jun 24 '15 at 07:51