cats icon indicating copy to clipboard operation
cats copied to clipboard

cats.data.ValidatedNel issue

Open kevingomu opened this issue 5 years ago • 1 comments

Hi all,

I am trying to run docker:publishLocal where I am faced with this error:


[error] /path/to/ClassA.scala:60:8: Cannot prove that cats.data.ValidatedNel[String,path.to.classB] <:< G[A].
[error]       .sequence
[error]        ^

Class A resides in project A, and classB is in project B, and they have this kind of structure:

|--projectName
        |-----project A
        |-----project B
|--build.sbt

The build.sbt looks like this:


lazy val projectA =
  project
    .in(file("projectName/projectA"))
    .enablePlugins(JavaAppPackaging, DockerPlugin)
    .dependsOn(ProjectRef(file("."), "projectB"))
    .settings(
        libraryDependencies ++= Seq("org.typelevel" %% "cats-core" % 2.1.0),
        scalacOptions += "-Ypartial-unification"
        ...
    )

lazy val projectB =
  project
    .in(file("projectName/projectB"))
    .dependsOn(ProjectRef(file("."), "anotherProject"))
    ...

I have researched around and I have added stuff like the "-Ypartial-unification", but to no avail:

plugins.sbt has this:

addSbtPlugin("org.lyranthe.sbt" % "partial-unification" % "1.1.2") The method that is throwing the error is:


def apply(v1: (crwm, icrwm)): Boolean = {
    val (_, cri) = v1

    validationCriteria
      .map(_.validate(cri))
      .sequence
      .map(_ => cri)
      .toEither
      .fold(validationErrors => {
        log.warn(s"""
             |CR didn't pass quality check(s):
             |${validationErrors.toList.mkString("\n")}
           """.stripMargin)
        false
      }, _ => true)
  }

Sorry I have to obfuscate the methods. If it is unclear, please let me know and I will provide any info that I could.

I'm running sbt version 1.2.7

Thank you so much.

kevingomu avatar Mar 06 '20 08:03 kevingomu

@kevingomu I doubt this problem has something to do with your project set up, it rather looks like your types don't work out. Unfortunately, your example code lacks important type information, so it's hard to help you based on this. I recommend extracting a minimal working (=reproducing behavior) example when you ask for help. That can be a little tricky, but often you'll find the fix for your problem while doing that already and if not, people can help you way more concrete.

Taking your example code and some guesses on what types you have there, I get the following snippet working nicely:

// Assuming you have some collection of checks you want to combine
val validationCriteria: List[Int => ValidatedNel[String, Int]] = List(
  i => Validated.condNel(i > 5, i, "Too small")
  // i => ...
)

val cri = 7 // Dummy input

validationCriteria
  .map(_.apply(cri)) // assuming your .validate takes the cri and produces a ValidatedNel
  .sequence // List[ValidatedNel[Error, SomeType]] => ValidatedNel[Error, List[SomeType]], can be combined with the previous .map to .traverse
  .map(_ => cri) // can be written as .as(cri), but seems unused anyway
  .toEither // unnecessary, Validated(Nel) has a .fold
  .fold(_ => false, _ => true) // simplified for readability

Maybe that helps you already. If not, please provide more details. The Gitter channel is btw a place where can get answers more quickly, plenty of helpful folks there. And we even have some docs on this topic: https://typelevel.org/cats/datatypes/validated.html#parallel-validation

ybasket avatar Mar 08 '20 11:03 ybasket