【发布时间】:2020-09-26 06:37:41
【问题描述】:
我在使用 Circe 并注意到一些我不太熟悉的东西,并想了解引擎盖下发生了什么?
从根本上说,这并不是一个真正的问题。我也只是在玩circe来测试一些东西。所以可以直接在JsonObject 中解码,但这不是重点。
val jobjectStr = """{
| "idProperty": 1991264,
| "nIndex": 0,
| "sPropertyValue": "0165-5728"
| }""".stripMargin
val jobject = decode[Json](jobjectStr).flatMap{ json =>
json.as[JsonObject]
}
我的问题是关于 Either 的 flapMap 签名、逆变和这里发生的事情:
我们有以下几种:
decode[Json](jobjectStr): Either[Error, Json]
json.as[JsonObject]: Decoder.Result[JsonObject]
circe 定义的地方
final type Result[A] = Either[DecodingFailure, A]
和
sealed abstract class DecodingFailure(val message: String) extends Error {
现在 flatMap 的签名是:
def flatMap[A1 >: A, B1](f: B => Either[A1, B1]): Either[A1, B1]
换句话说,只谈论类型就像我的代码正在做的那样
Either[Error, Json] flatMap Either[DecodingFailure, JsonObject]
因此我的问题是: DecodingFailure >: Error 不是真的
确实,完整表达式的类型是:
decode[Json](jobjectStr).flatMap{ json =>
json.as[JsonObject]
}: Either[Error, JsonObject]
因此我很困惑,因为我的理解是,Either 的第一个参数的类型在 flatMap 签名中是逆变的。这里似乎正在进行一些奇怪的最小上限推理......但我不确定为什么或是否是这种情况。
有什么解释吗?
【问题讨论】:
-
首先,Either 在它们的两个类型参数上都是协变。
标签: scala functional-programming type-inference circe