在Scala中的通用curried方法中键入推断
发布时间:2020-12-16 08:45:38 所属栏目:安全 来源:网络整理
导读:我正在尝试 Scala并且稍微混淆了类型推断问题. 鉴于下面的定义,它成功编译: case class SequentialHistory[+E](events: Seq[E])trait Eventcase class SampleEvent(value: String) extends Eventdef addEvent[E,E2 : E](event: E)(history:SequentialHistor
我正在尝试
Scala并且稍微混淆了类型推断问题.
鉴于下面的定义,它成功编译: case class SequentialHistory[+E](events: Seq[E]) trait Event case class SampleEvent(value: String) extends Event def addEvent[E,E2 >: E](event: E)(history:SequentialHistory[E2]): SequentialHistory[E2] = history.copy(events = event +: history.events) 我想了解为什么类型推断不能正常工作并编译: val hist = SequentialHistory(Seq.empty[Event]) //hist: SequentialHistory[Event] = SequentialHistory(List()) val histWithEvent = addEvent(SampleEvent("Does not compile"))(hist) //error 导致编译错误: Error:(21,62) type mismatch; found : SequentialHistory[Event] required: SequentialHistory[SampleEvent] addEvent(SampleEvent("Does not compile"))(hist) ^ 但是,如果我在addEvent方法定义中交换参数列表: def addEvent2[E,E2 >: E](history: SequentialHistory[E2])(event: E): SequentialHistory[E2] = history.copy(events = event +: history.events) 这将解决问题,正确推断类型和下面的代码片段编译: val hist2 = SequentialHistory(Seq.empty[Event]) //hist2: SequentialHistory[Event] = SequentialHistory(List()) val histWithEvent2 = addEvent2(hist)(SampleEvent("Compiles")) //histWithEvent1: SequentialHistory[Event] = // SequentialHistory(List(SampleEvent1(Compiles))) 为什么Scala编译器无法在第一版addEvent中正确推断类型? 解决方法
我无法通过引用Scala规范中的编译器代码或引用来解释它,但这是我的推理.
当你的函数有多个参数列表时,它是“咖喱”的,所以它是第一个返回另一个函数的参数的函数,等等.所以如果你试图将它只应用于一个参数,所有类型都将被推断: scala> val partial = addEvent(SampleEvent(""))(_) partial: SequentialHistory[SampleEvent] => SequentialHistory[SampleEvent] = <function1> 现在你不能用更宽的类型传递第二个参数.这里发生的是eta expansion.但是另一种方法是不行的: scala> val partial = addEvent2(hist)(_) <console>:14: error: missing parameter type for expanded function ((x$1) => addEvent2(hist)(x$1)) val partial = addEvent2(hist)(_) 这里E2由hist参数修复,但是编译器不能推断E.但是如果你提供它两个参数,它会看到它们的类型符合限制.我认为在这个意义上,第二个定义与def addEvent2 [E,E2>:E](事件:E,历史:SequentialHistory [E2])的定义相同. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |