2017-11-13 11 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].

깔끔한 아이디어들? 형식이없는 입력 가능을 보았지만 내 경우에는 그것을 사용할 수있는 방법이 확실하지 않습니다. 타입 레벨 스칼라로 바꾸는 것 (옵션 매개 변수 매칭, woohoo를 해결한다고 생각합니다)은 옵션이 아닙니다.

깔끔한 아이디어가 있습니까? : D 편집

: 여기 내가 시도했지만 컴파일러 문제로 실행 접근 방식입니다 : 당신은 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[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 { case a : A => ... case b : B => ... } Param은 봉인 된 특성이므로 매우 안전합니다. – C4stor

+0

사실이지만, 여기에는 구체적인 값이 있습니다 , 그리고 아닙니다. 함수. 필자의 경우 포함 된 타입은 일반적으로'Param' 타입의 타입이 아닙니다. –

+0

Config [T <: Param]이 포함 된 유형이 필수적으로 Param의 하위 유형이므로 일치 조항에서 열거 가능하다는 것을 알기 때문에 약간 혼란 스럽습니다. 나는 그 때 당신의 필요를 정확하게 이해하지 못했을 까봐 두려워! – C4stor

답변

1

다음 코드는 컴파일 :

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 value를 해결하지만 여전히 실용적인 값을 줄입니다. –