2017-11-13 4 views
1

私は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にパラメータ化の様々なタイプ、私はいつもそれにもかかわらず通知を行います...

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] => 
} 

をしかし、私たちが知っているように型消去は、この痛みます:

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

私はそれらの各パターンマッチのことができるようにするのが大好きです高級品と一致する必要がありますF[T <: Param].

すてきなアイデアはありますか?私は形のないタイプ可能な文字を見てきましたが、私の場合はどのように使うことができるかわかりません。 typelevel scala(これは型パラメータのマッチング、woohooを解決すると思います)に切り替えることはオプションではありません。

すてきなアイデアの人ですか? :D

EDIT:ここに は、私が試したアプローチですが、コンパイラの問題に遭遇:

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) => 
    } 

} 
+0

あなたが望むタイプのconfig.somethingでマッチする: config.param match { ケースa:A => ... ケースb:B => ... } Paramは密閉された特性なので、かなり安全です。 – C4stor

+0

それは本当ですが、そこには具体的な値があります、そして、例えば機能。私のケースでは、包含される型は通常、 'Param'型の型ではありません。 –

+0

Config [T <:Param]は、含まれている型が必然的にParamのサブタイプであり、したがってmatch節で列挙可能であることを示していると理解しているので、ちょっと混乱しますか?私はあなたの必要性を正しく理解していないのではないかと恐れています! – C4stor

答えて

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) => ??? 
    } 

    } 
+0

良い点、ありがとう!残念ながら、IntelliはAnyがパラメータなしであり、実用的な値を少し減らしているので意味をなさない、Any [A]/Any Any [B]などとして 'value'を解決します。 –

関連する問題