2012-04-05 3 views
6

바운드 형식 매개 변수가 Animal[A <: String] 인 클래스 정의가 주어지면 Scala 컴파일러가 B <: StringAnimal[B]에서 유추하지 않는 것으로 보입니다. 추론은 허용됩니까? 추측을하기 위해 컴파일러를 돕는 방법?언 바운드 형식 매개 변수가있는 멤버를 사용하여 사례 클래스를 정의하는 방법은 무엇입니까?

다음은이 추론의 부족이 문제가되는 사례 클래스의 구체적인 예입니다.

sealed trait Person[+T <: Person[T]] 
case class Student() extends Person[Student] 
case class Professor() extends Person[Professor] 

은 내가 예를 val p: Person[_] = Student()를 들어, Person[_]의 변수로 인스턴스화 할 수있는 경우 클래스 University를 정의해야

는 다음의 경우 클래스 계층 구조를 생각해 보자. 나는이 다음과 같은 정의 작업 것이라고 생각 :

case class University(p: Person[_]) 

하지만이 오류와 함께 컴파일 실패 : 나는 경우 클래스가 컴파일 University의 형식 매개 변수를 결합하면

type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]] 

가 (그것도으로 컴파일

case class BoundUniversity[P <: Person[P]](p: Person[P]) 

그러나이 매개 변수화 버전이 될 수 없습니다 : 내가 case 키워드를 삭제하지만 내 경우 옵션)가 아닌 경우 무제한의 매개 변수

이 같은 오류가 같은 바운드 인수하는 방법에 대한 일
inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]] 

:

def general[P <: Person[P]](p: P) = println(p) 

그래서 이것이

val p: Person[_] = Student() 
BoundUniversity(p) 

실패가 컴파일 : 유형 Person[_]의 억제 할 수없는 변수로 인스턴스화 클래스 생성자에만 국한되지는 않습니다.

두 질문 :

  1. 유형 Person이 유형의 각 인스턴스가 그 경계를 존중하는 보험에 가입되도록, 파라미터 경계 Person[+T <: Person[T]]로 정의된다 val p: Person[P]이 의미 P <: Person[P] 그; 또는 나는 무엇인가 놓치고 있냐? 그렇다면 컴파일러에게 어떻게하면 불평하지 않도록 할 수 있습니까?

  2. 어떻게/case class University(p: Person[_])과 같은 언 바운드 형식 매개 변수가있는 멤버를 사용하여 사례 클래스를 정의 할 수 있습니까?

+0

'T'는 공변이어야합니까? – leedm777

+0

@dave 내 특별한 경우에'T'는 공변이어야하지만 이것이 문제를 변화시키지 않는다고 생각합니다 : 소개 예제를보십시오. –

+0

[추상 유형] (http://docs.scala-lang.org/tutorials/tour/abstract-types.html)을 사용하여 어딘가에 얻을 수 있지만 [꽤 많이 변하지 않습니다] (http : // stackoverflow. com/a/5359015/115478). – leedm777

답변

2

유형 X[_]은 거의 원하는 것이 아닙니다. 유형에 _을 사용하면 기본적으로 매개 변수가 무엇인지 신경 쓰지 않는다는 것을 의미합니다. 사용하지 않아도되기 때문입니다.

어쨌든 컴파일됩니다. 실존 적 유형은 자신이하는 까다로운 일이지만 도로 아래로 물지는지도 모르지만 ...

case class University(p: Person[t] forSome { type t <: Person[t] }) 
+0

좋은 실존 유형, 감사합니다! 이것은 컴파일되지만 'val p : Person [_] = Student();로 인스턴스화 할 수 없습니다. 대학 (p)'. 필자가 언급 한'Person [_]'타입은 List [Person [_]] (Student(), Professor())리스트에서 나온 것입니다. 'List (Student(), Professor())는 컴파일되지 않습니다. 나는 여기에 패턴이 있다고 느낀다. 그러나 손가락을 그 위에 놓을 수는 없다 ... –

+0

사실 내 Eclipse에서는 오류를 표시하지 않지만 'scalac'에서는 컴파일하지 않는다. 형식 mismtach, 발견'Person ((some other) _1 (method equals)에서) type (some other) _1 (method equals) <: schemdesc.hierarchy.eval.Person [_0]', 필수'Person [_ < : schemdesc.hierarchy.eval.Person [_0]]' –

+0

@jullybobble 위 라인이 컴파일됩니다 - 테스트 해 보았습니다. 컴파일 문제가 생기면 다른 일을하고있는 것입니다. 그리고 당신은'Person [_]'을 사용할 수 없습니다 - 작동하지 않을 것입니다. 위의 실존 타입을 사용하려면 그것을 사용해야합니다. –

관련 문제