模式匹配更高的参数

时间:2017-11-13 14:13:55

标签: scala pattern-matching higher-kinded-types

我有一个带有4个子类的ADT的域模型,例如

sealed trait Param

case class A(...) extends Param
case class B(...) extends Param
case class C(...) extends Param
case class D(...) extends Param

在这个Param上参数化的各种类型,例如

case class Config[T <: Param](...)
case class Parser[T <: Param](...)
case class Price[T <: Param](...)

我希望能够对每一种模式进行匹配:

val config: Config[T] = ??? 
//Assuming T <: Param, as defined above
config match {
  case confA: Config[A] => 
  case confB: Config[B] => 
  case confC: Config[C] => 
  case confD: Config[D] => 
}

但是,正如我们所知,类型擦除使这成为一种痛苦......

请注意,我总是需要匹配更高级别的F[T <: Param].

任何干净的想法?我看过无形的可打字,但不确定它在我的情况下如何使用它。切换到类型级别scala(我认为解决类型参数匹配,woohoo)不是一种选择。

人们有什么好看的想法吗? :d

编辑: 这是我尝试过但遇到编译器问题的方法:

sealed trait Param

case class A() extends Param 
case class B() extends Param
case class C() extends Param
case class D() extends Param

sealed trait ForParam[F[T <: Param], T <:Param] {
  def value: F[T]
}
case class ForParamA[F[_]](value: F[A]) extends ForParam[F, A]
case class ForParamB[F[_]](value: F[B]) extends ForParam[F, B]
case class ForParamC[F[_]](value: F[C]) extends ForParam[F, C]
case class ForParamD[F[_]](value: F[D]) extends ForParam[F, D]

object ForParam {
  case class Example[T <: Param](f: T => String)

  val exampleFormParam: ForParam[Example, _] = ???
  //The below does not compile:
  //  [error]      constructor cannot be instantiated to expected type;
  //  [error]       found   : ForParamD[F]
  //  [error]       required: ForParam[ForParam.Example,_$2] where type _$2
//  I think I run into issue related to https://github.com/scala/scala/pull/6069
  exampleFormParam match {
    case ForParamA(value) =>
    case ForParamB(value) =>
    case ForParamC(value) =>
    case ForParamD(value) =>
  }

}

1 个答案:

答案 0 :(得分:1)

您在ForParamA

中失去了类型参数的界限

以下代码编译:

  sealed trait Param

  case class A() extends Param
  case class B() extends Param
  case class C() extends Param
  case class D() extends Param

  sealed trait ForParam[F[_ <: Param], T <: Param] {
    def value: F[T]
  }
  case class ForParamA[F[_ <: Param]](value: F[A]) extends ForParam[F, A]
  case class ForParamB[F[_ <: Param]](value: F[B]) extends ForParam[F, B]
  case class ForParamC[F[_ <: Param]](value: F[C]) extends ForParam[F, C]
  case class ForParamD[F[_ <: Param]](value: F[D]) extends ForParam[F, D]

  object ForParam {
    case class Example[T <: Param](f: T => String)

    val exampleFormParam: ForParam[Example, _] = ???
    exampleFormParam match {
      case ForParamA(value) => ???
      case ForParamB(value) => ???
      case ForParamC(value) => ???
      case ForParamD(value) => ???
    }

  }