应用程序中的 scalaz 版本更新后 DecodeJson 不工作

DecodeJson not working after scalaz version update in application

我尝试将 scalaz 版本升级到 7.2.18。在之前的版本中,以下代码块运行良好。

  implicit val decode: DecodeJson[Uuid] =
    DecodeJson( cursor =>
      cursor.as[String].flatMap( str =>
        DecodeResult(
            \/.fromTryCatchThrowable[Uuid,IllegalArgumentException](from(str))
              .leftMap(exc => (exc.getMessage, cursor.history))
        ) ) )

但是我升级了版本,DecodeResult(...)块报错:

Type Mismatch, 
    expected: Either((String, CursorHistory), NotInferredA)
    actual  : \/((String, CursorHistory),Uuid)

如果有人能告诉我错误发生的原因以及上述块的正确实现,我将不胜感激。

我怀疑您将 Argonaut 库用于 JSON,并且您的 DecodeJsonDecodeResult 来自那里。很难猜测它之前究竟是如何工作的,因为您没有指定升级的这些库的版本以及您拥有的其他依赖项(即代码何时工作)。

目前的问题是 DecodeResult 期望来自标准 Scala 库的 scala.util.EitherEither 而你给出的是功能丰富的 scalaz.\/相当于 Scalaz 库中的 Either。此外,这些类型是同构的(具有相同的形状)并且可以很容易地相互转换,因为编译器知道 scala.util.Eitherscalaz.\/ 是两个不相关的 类。可能最简单的修复方法是使用 \/.toEither 方法来转换值:

implicit val decode: DecodeJson[Uuid] =
  DecodeJson(cursor =>
    cursor.as[String].flatMap(str =>
      DecodeResult(
        \/.fromTryCatchThrowable[Uuid, IllegalArgumentException](Uuid.from(str))
          .leftMap(exc => (exc.getMessage, cursor.history)).toEither
      )))

或者,您可以尝试查找之前是什么依赖项带来了从 \/Either 的一些自动转换。或者你可以自己写:

object ScalaZEitherHelper {
  implicit def scalaZToStd[A, B](scalazValue: A \/ B): Either[A, B] = scalazValue.toEither
}

然后你的原始代码会像你一样编译 import ScalaZEitherHelper._