Scala泛型推理/值声明中的下界

时间:2014-08-08 10:25:10

标签: scala generics inference

我是Scala的新手,并且一直试图在Lift中开发一个数据网格,这样我就可以舒适地显示数据(这也很适合我作为一种Scala / Lift练习,以便更好地掌握的语言)。无论如何,我似乎都坚持使用泛型推理。

我有一个抽象的Grid类,所有的具体网格都可以扩展。然后,他们通过columns字段定义其列。我想实现默认排序,但无法弄清楚如何正确地进行必要的推理。这是(非常简化的)代码:

//Lift classes
trait Mapper[A <: Mapper[A]]
trait MappedField[FieldType, OwnerType <: Mapper[OwnerType]]
final case class OrderBy[O <: Mapper[O], T](field: MappedField[T, O])

//models
class Items extends Mapper[Items] {
  object name extends MappedField[String, Items]
}
object Items extends Items

//Grid
abstract class Grid {
  case class Column[O <: Mapper[O]](val label: String, val alias: String, val column: MappedField[_, O])

  val columns: List[Column[_]]

  def sort(by: List[String]) = {
    //HERE I get the inferred type arguments do not conform to method apply's type parameter bounds...
    columns.filter(c => by.contains(c.alias)).map(c => OrderBy(c.column))
  }
}

class ItemsGrid extends Grid {
  val columns = List(new Column[Items]("Name", "name", Items.name))

  def sortWorking(by: List[String]) = {
    val col = new Column[Items]("Name", "name", Items.name)
    OrderBy(col.column)
  }
}

...不编译。我在OrderBy的{​​{1}}方法的sort方法中遇到以下错误:推断类型参数[ $ 2, $ 1]符合方法apply的类型参数bounds [O&lt ;: main.Mapper [O],T]

由于GridsortWorking中的虚拟排序工作得很好,问题必须隐藏在Items的{​​{1}}中。我无法使用下限和存在来正确地声明类型,并且无法说服编译器推断出List[Column[_]]具有正确的类型,它们的列表也是如此。

任何想法或指向我正确的方向是非常感谢! Tadeáš

1 个答案:

答案 0 :(得分:2)

下一行的问题:

val columns: List[Column[_]] // in '_'

我建议将类型参数转换为类型变量(使用嵌入式多态):

//Grid
abstract class Grid {
  trait Column {
    type F
    type O <: Mapper[O]   

    val label: String
    val alias: String
    val column: MappedField[F, O]
  }

  object Column {
    def apply[F1, O1 <: Mapper[O1]]
      (l : String, a : String, c : MappedField[F1, O1]) =
        new Column {
          type F = F1
          type O = O1

          val label = l
          val alias = a
          val column = c
        }
  }

  val columns: List[Column]

  def sort(by: List[String]) = {
    columns.filter(c => by.contains(c.alias)).map(c => OrderBy(c.column))
  }
}

Grid实例将如下所示:

class ItemsGrid extends Grid {
  val columns = List(Column("Name", "name", Items.name))

  def sortWorking(by: List[String]) = {
    val col = Column("Name", "name", Items.name)
    OrderBy(col.column)
  }
}