通过使用变量中的类型来调用类型类

时间:2018-07-21 09:28:13

标签: scala

我有两种类型的类型,其中一种包含另一种类型

sealed trait Version
case class Version1() extends Version
case class Version2() extends Version

case class MyModel1(msg: String, version: Version)
case class MyModel2(msg: String, version: Version)

trait Validate[M, V] {
  def run : Boolean
}

object Validators {
  implicit object ValidateModel1 extends Validate[MyModel1, Version1] {
    override def run: Boolean = true
  }
  implicit object ValidateModel2 extends Validate[MyModel1, Version2] {
    override def run: Boolean = true
  }
}

我想这样调用我的类型类:

object App {

  def main(args: Array[String]): Unit = {
    val model = MyModel1("Test", Version1())
    validate(model)
  }

  def validate(model: MyModel1) {
    import Validators._    

    val v = implicitly[Validate[MyModel1, model.version.type]]
    v.run
  }
}

但这不起作用。

  

错误:(34,23)找不到参数e的隐式值:   com.playground.Validate [com.playground.MyModel1,model.version.type]       val v =隐式[Validate [MyModel1,model.version.type]]错误:(34,23)隐式方法的参数不足:(隐式   e:   com.playground.Validate [com.playground.MyModel1,model.version.type])com.playground.Validate [com.playground.MyModel1,model.version.type]。   未指定的值参数e。       val v =隐式[Validate [MyModel1,model.version.type]]

model.version.type代替Version1

任何想法如何通过指向Version中的MyModel1类型来调用我的类型类吗?

随时建议一个更明确的标题:)

谢谢

1 个答案:

答案 0 :(得分:1)

请记住,隐式是在编译时解析的,以便编译器无法知道是否在内部

case class MyModel1(msg: String, version: Version) 

版本的类型为Version1Version2。只是不知道。如果您需要使用该信息,则需要通过通用参数抽象类型(将通过帮助程序使用)将其保留在类的签名中。类型,它将变成通用类型,因此您可以在签名中使用它并表达类型关系)

所以解决方案是像这样泛化模型

case class MyModel1[V<:Version](msg:String, version:V)