简体   繁体   English

Scala:下限上下文泛型需要类型不匹配_$1

[英]Scala: Type mismatch required _$1 for lower context bound generics

I am having difficulty resolving this type mismatch compilation error我很难解决这种类型不匹配的编译错误

I have a series of Sources that I want to implement the strategy pattern to process the appropriate type我有一系列的 Sources 想要实现策略模式来处理适当的类型

sealed trait Source
case class SourceA extends Source
case class SourceB extends Source

My preprocessor consists of a number of strategies that will process the appropriate case class我的预处理器包含许多处理适当案例类的策略

trait SourceStrategy[T <: Source] {    
    def isApplicable(source: Source): Boolean    
    def preprocess(source: T): Whatever
}

The idea is that a SourceStrategy implementation will exist for each case class above这个想法是对于上面的每个案例类都将存在一个 SourceStrategy 实现

I want to do something like this, whereby I loop through the appropriate strategies, find the one that is applicable and then invoke that one我想做这样的事情,通过适当的策略循环,找到适用的策略,然后调用该策略

class MyPreprocessor (strategies: Set[SourceStrategy[_ <: Source]]) {
  def performPreprocessing(source: Source) = {
    val preprocessor = strategies.filter(b => b.isApplicable(source)).head
    preprocessor.preprocess(source)
  }
}

I am getting a mismatch between _$1 and Source in this last line.我在最后一行中发现_$1Source不匹配。

I understand the reason that this occurs but I'm just not sure how to resolve it in a clean manner我了解发生这种情况的原因,但我不确定如何以干净的方式解决它

Either you want to check that a current strategy is applicable to a current source at compile time or you want to check this at runtime.您要么想在编译时检查当前策略是否适用于当前源,要么想在运行时检查这一点。

If you do at runtime then there is not much sense in making SourceStrategy generic如果你在运行时这样做,那么让SourceStrategy泛型就没有多大意义

trait SourceStrategy {
  def isApplicable(source: Source): Boolean
  def preprocess(source: Source): Whatever
}
class MyPreprocessor (strategies: Set[SourceStrategy]) {
  def performPreprocessing(source: Source) = {
    val preprocessor = strategies.filter(b => b.isApplicable(source)).head
    preprocessor.preprocess(source)
  }
}

If you do at compile time then you can use heterogeneous collection and type class如果您在编译时这样做,那么您可以使用异构集合和类型类

trait PerformPreprocessing[L <: HList, T <: Source] {
  def performPreprocessing(strategies: L, source: T): Whatever
}
object PerformPreprocessing {
  implicit def recur[T <: Source, S, L <: HList, T1 <: Source](implicit
    performPreprocessing: PerformPreprocessing[L, T1]
  ): PerformPreprocessing[S :: L, T1] =
    (strategies, source) => performPreprocessing.performPreprocessing(strategies.tail, source)
  implicit def base[T <: Source, S <: SourceStrategy[T], L <: HList]: PerformPreprocessing[S :: L, T] =
    (strategies, source) => strategies.head.preprocess(source)
}

class MyPreprocessor[L <: HList](strategies: L) {
  def performPreprocessing[T <: Source](source: T)(implicit
    performPreprocessing: PerformPreprocessing[L, T]
  ): Whatever =
    performPreprocessing.performPreprocessing(strategies, source)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM