2010-12-14 1 views
2

특성을 감안할 때 T추상 클래스/특성 및 불변 함수

trait T { 
    def v: Int 
    def +(t: T): T 
} 

다음 클래스 A

case class A(v: Int) extends T { 
    def +(a: A) = A(v + a.v) 
} 

T의 유효한 하위 유형이 아닙니다. A.+의 서명은 모든 구현이 A 유형의 객체뿐만 아니라 T 유형의 객체를 허용 할 수 있어야하지만 A.+의 유형은 A 유형의 요소 만 허용하므로 A.+의 구현은 너무 제한적입니다. 지금까지, 너무 합리적인.

T의 구현을 제한적으로 허용하려면 다음과 같이 TA의 선언을 수정할 수 있습니다.

trait T[This <: T[This]] { 
    def v: Int 
    def +(t: This): This 
} 

case class A(v: Int) extends T[A] { 
    def +(a: A) = A(v + a.v) 
} 

분명히 형식 서명을 날려 버립니다.

T의 구현이 자신의 유형의 객체와 호환되어야한다고 선언하는 또 다른 방법이 있습니까?

첫 번째 EDITLandei's answer below

실제로 회신하는 동안 현재 서명은 T이 발생하는 다른 서명을 단축하지 않습니다.

trait C[D <: T[D], S] { self: S => 
    def +(perm: D): S 
    def matches(other: S): Boolean 
} 

답변

1

당신은 자기 유형을 사용할 수 있습니다

trait T[S] { 
    self:S => 
    def v: Int 
    def +(t: S): S 
} 

case class A(v: Int) extends T[A] { 
    def +(a: A) = A(v + a.v) 
} 
+0

위의 "제 1 편집"을 참조하십시오. 그럼에도 불구하고, 나는 셀프 타입 주석을 전에 고려하지 않았다. –

+1

나는 이것을위한 일반적인 해결책을 모른다. 의도와 클래스 계층 구조에 따라 유형 클래스 패턴 (암시 적 사용)이 적용될 수 있습니다 (예 : Numeric 참조). 또 다른 시도는 유형 변수 (D를 "내부"특성으로 끌어 들이기 위해)입니다. – Landei

1

당신은 유형들과 그것을 할 수 있습니다. 나는 당신이 여기서 단호하게 "짧은"브랜드인지 정확히 알지 못합니다. 약간의 중복성이 있지만, 반면에 유형 매개 변수는 큰 괄호 절약을 전달하지 않습니다.

+0

제안 사항의 차이점은 TT의 하위 유형을 This에 할당 할 수 있다는 것입니다. 저는 mhs가 이것을 클래스 자체의 타입으로 제한하려고한다고 생각합니다. 그러나, 후속 질문 (특성 D)에 대한 답은 귀하의 접근 방식과 어떻게 유사합니까? – Landei