为什么 circe `or` 函数(显然是一元函数)与需要二元运算的 reduceLeft 一起工作?
Why does the circe `or` function (an apparently unary function) work with reduceLeft which requires a binary op?
A 和我正在做一些关于 encode/decode 一些 ADT 的工作,我们 运行 研究了一些我们根本不了解的功能。 circe 文档中给出的示例按预期工作,但在深入研究后 - 尚不清楚为什么解码示例有效,因此我们很难推理如何在需要时进行修改。
功能(来自Circe Examples about ADTs):
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。 Why/how 如果 or
函数似乎不符合 reduceLeft
要求的类型,这项工作是否可行?
or
是一个 方法 的一个参数,但不要忘记 this
.
decoder1.or(decoder2)
(又名 decoder1 or decoder2
)是关于 decoder1
、decoder2
.
的二元函数
final abstract class Int private extends AnyVal {
...
/** Returns the sum of this value and `x`. */
def +(x: Int): Int
...
}
但您仍然可以添加两个 Int
:1 + 1
又名 1.+(1)
。
所有方法都比其签名中列出的多一个“参数”,即this
。
(所有普通参数都是静态解析,this
是动态解析。)
考虑以下简化类比
case class Score(v: Double) {
def add(that: Score): Score = Score(this.v + that.v)
}
val l = List[Score](Score(1.1), Score(2.2), Score(0.1))
l.reduceLeft((a: Score, b: Score) => a.add(b)) // unsugared
l.reduceLeft((a: Score, b: Score) => a add b) // infix notation
l.reduceLeft(_ add _) // anonymous function placeholder parameter
注意infix notation and anonymous function placeholder parameter
的用法
A 和我正在做一些关于 encode/decode 一些 ADT 的工作,我们 运行 研究了一些我们根本不了解的功能。 circe 文档中给出的示例按预期工作,但在深入研究后 - 尚不清楚为什么解码示例有效,因此我们很难推理如何在需要时进行修改。
功能(来自Circe Examples about ADTs):
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。 Why/how 如果 or
函数似乎不符合 reduceLeft
要求的类型,这项工作是否可行?
or
是一个 方法 的一个参数,但不要忘记 this
.
decoder1.or(decoder2)
(又名 decoder1 or decoder2
)是关于 decoder1
、decoder2
.
final abstract class Int private extends AnyVal {
...
/** Returns the sum of this value and `x`. */
def +(x: Int): Int
...
}
但您仍然可以添加两个 Int
:1 + 1
又名 1.+(1)
。
所有方法都比其签名中列出的多一个“参数”,即this
。
(所有普通参数都是静态解析,this
是动态解析。)
考虑以下简化类比
case class Score(v: Double) {
def add(that: Score): Score = Score(this.v + that.v)
}
val l = List[Score](Score(1.1), Score(2.2), Score(0.1))
l.reduceLeft((a: Score, b: Score) => a.add(b)) // unsugared
l.reduceLeft((a: Score, b: Score) => a add b) // infix notation
l.reduceLeft(_ add _) // anonymous function placeholder parameter
注意infix notation and anonymous function placeholder parameter
的用法