2016-10-12 3 views
0

공통 하부 경계를 정의 스칼라 컴파일러/IF 다른 표현에 사용되는 값의 최소 공통 수퍼 복귀 타입을 정의 할 수있다 계층 :다음 함수의 파라미터

class X 
class A extends X 
class B extends X 

함수 위 condX의 값을 반환하는 것으로 정의된다.

AB 유형 파라미터는 cond 함수의 정의에 있다면

그러나, 그 반환형 Any이다

def cond[A, B](b: Boolean, t: A, f: B) = if (b) t else f 

는 컴파일러 형의 최소 공통 퍼를 사용하게 할 수있다 매개 변수?

내가 성공하지 않고, 다음의 몇 가지 변화를 시도 :

def cond[A, B, R >: A with B](b: Boolean, t: A, f: B): R = if (b) t else f 
def cond[A, B, R](b: Boolean, t: A, f: B)(implicit ev1: A <:< R, ev2: B <:< R): R = if (b) t else f 

편집을 : 위의 질문은 과도하게 단순화된다. 당신이 정적으로 LUB을 알고있는 경우

class C[A](b: Boolean, t: A) { 
    def cond[B](f: B) = if(b) t else f 
} 

답변

1

, 그 다음은 일반적으로 충분합니다 :

def cond[T](b: Boolean, t: T, f: T) = if (b) t else f 

스칼라가 자동으로 (그 이상 상한에 LUB를 인수의 유형을 업 캐스팅합니다) : 당신이 정확한 유형을 필요로하는 경우

scala> cond(true, new A, new B) 
res0: X = [email protected] 

하지만, 암시 적 해결을위한 예를 들어, 내가 벨 다음과 같은 트릭 작동합니다 ieve :

def cond[A, B, C >: A](b: Boolean, t: A, f: B with C): C = if (b) t else f 

여기 AB는 인수의 정확한 종류 및 C는 LUB입니다. CA : C >: A의 상위 유형 제한 조건을 갖지만 두 번째 인수 유형도 f: B with C으로 정의되어 있으므로 AB의 LUB로 추정됩니다. @nikhil하는

import reflect.runtime.universe._ 
def cond[A, B, C >: A](b: Boolean, t: A, f: B with C)(
    implicit ta: TypeTag[A], 
      tb: TypeTag[B], 
      tc: TypeTag[C] 
): C = { 
    println(ta) 
    println(tb) 
    println(tc) 
    if (b) t else f 
} 

scala> cond(true, new A, new B) 
TypeTag[A] 
TypeTag[B] 
TypeTag[X] 
res5: X = [email protected] 
1

당신은 A와 B에 상위 타입의 범위를 적용 할 수 있습니다 : 사실 내 진짜 문제는 이미 해결 된 유형 매개 변수 중 하나가 있었다. 당신이 인수의 exacta 유형이 필요하지 않은 경우

def cond[A <: C, B <: C,C](b: Boolean, t: A, f: B) = if (b) t else f 
0

감사 @Kolmar 답변 나는이 솔루션까지 올 수 :

우리는 다음 코드로이 정의와 올바른 형식 유추를 확인할 수 있습니다

class C[A](b: Boolean, t: A) { 
    def cond[B <: R, R >: A](f: B): R = if(b) t else f 
}