A 和我正在使用 circe 对一些 ADT 进行编码/解码,我们遇到了一些我们根本不了解的功能。circe 文档中给出的示例按预期工作,但在深入研究后 - 不清楚为什么解码示例有效,因此我们很难推理如何在需要时进行修改。
功能(来自关于 ADTs 的 Circe 示例):
import cats.syntax.functor._
import io.circe.{ Decoder, Encoder }, io.circe.generic.auto._
import io.circe.syntax._
object GenericDerivation {
// Encoder Redacted
implicit val decodeEvent: Decoder[Event] =
List[Decoder[Event]](
Decoder[Foo].widen,
Decoder[Bar].widen,
Decoder[Baz].widen,
Decoder[Qux].widen
).reduceLeft(_ or _)
}
我明白了 - 基本上是从这个列表中选择第一个工作的解码器 - 有道理但是(!)
or
似乎是一个采用名称参数的一元函数。类型签名是:
final def or[AA >: A](d: => Decoder[AA]): Decoder[AA]
并且reduceLeft
(来自 IterableOnce)需要一个二元函数。类型签名是:
def reduceLeft[B >: A](op: (B, A) => B): B
然后我的大脑爆炸了。我显然错过了一些东西,无法弄清楚。
该示例最明确地适用于转换 ADT。or
鉴于该功能似乎不符合所需的类型,为什么/如何工作reduceLeft
?