我试图将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,你的DecodeJson
和DecodeResult
来自那里。很难猜出它之前是如何工作的,因为您没有指定升级的库的版本以及您拥有的其他依赖项(即代码工作时)。
目前问题来自DecodeResult
期望来自标准Scala库的scala.util.Either
即Either
这一事实,而你提供的是scalaz.\/
,这是与Scalaz库中的Either相当的特征丰富。这些类型也是同构的(具有相同的形状)并且可以很容易地相互转换,只要编译器知道scala.util.Either
和scalaz.\/
是两个不相关的类。可能最简单的解决方法是使用\/.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._