gpt4 book ai didi

scala - 如何结合两个消费者?

转载 作者:行者123 更新时间:2023-12-01 00:45:46 27 4
gpt4 key购买 nike

给定消耗类型 T 值的简单特征:

trait Consumer[-T] extends (T => Unit) {
def +[U, P](other: Consumer[U]): Consumer[P] = ???
}

如何实现 +将两个消费者组合成一个接受 AnyRef 的有效父类(super class)型或更宽的 AnyVal 类型的函数?对于以下情况:

-AnyRefs 具有共同的父类(super class)型:
trait Base
trait A extends Base
trait B extends Base

val c1: Consumer[A] = _
val c2: Consumer[B] = _
val cc = c1 + c2 //cc must have type of Consumer[Base]

-AnyVals:
val c1: Consumer[Int] = _
val c2: Consumer[Long] = _
val cc = c1 + c2 //cc must have type of Consumer[Long]

最佳答案

您正在尝试实现偏函数的概念。这样做时,您需要意识到您正在为动态性牺牲类型安全性。在强类型语言中,如果没有一些显式的 hack,您通常无法做到这一点,例如类型转换或差异规则缓解。

例如,标准 Scala 的 PartialFunction为您做到这一点:它允许将一个函数分配给另一个禁用参数逆变检查的函数。例如,具有类型层次结构

trait Animal
case class Dog() extends Animal
case class Cat() extends Animal

,它允许“分配”类型为 Dog => T 的函数到 Animal => T 类型的函数(与逆变规则相矛盾的内容):
val pf: PartialFunction[Animal, Unit] = {
case Dog() => println("dog")
}

以运行时可能出现的匹配错误为代价:
pf(Cat()) // MatchError

因此,通常要在 Scala 中组合多个消费者,您可以在定义部分函数时执行与 Scala 语言完全相同的技巧 - 将消费者参数方差更改为协变,即 -T+T .为此,请使用 @uncheckedVariance注解:
trait Consumer[+T, +V] extends (T@uncheckedVariance ⇒ V) {
def handle(command: T@uncheckedVariance): V
}

这种差异允许有一个消费者查找表:
val lookup: Map[Class[_], Consumer[Animal]] = Map(
classOf[Dog] → dogConsumer,
classOf[Cat] → catConsumer
)

可用于实现基于(在本例中)类类型的调度。

关于scala - 如何结合两个消费者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34598203/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com