2014-11-03 3 views
1

가정하자 나는 유형 A, BC, 그리고 오버로드 방법이 있습니다포장 과부하 기능

def foo(a: A): C 
def foo(b: B): C 
다음

나는 작동 코드 (복잡한) 조각이 가정을 유형은 C입니다. 내가하고 싶은 것은 두 유형 A 또는 B 취하는 방법이다 : 나는 bar의 두 가지 버전을 쓸 수 물론

def bar(x: [A or B]) = { 
    val c = foo(x) 
    // Code that works with c 
} 

를, 유형 AB를 취할 과부하하지만,이 경우, 여러가 bar처럼 동작하는 함수들, 그리고 과부하 된 버전을 가진 바보가 될 것입니다. (실제 경우에는 foo의 세 가지 버전이 있습니다).

C 스타일 매크로가 여기에 완벽 할 것이므로 Scala 매크로를 살펴 보았습니다. 어색한 부분은 스칼라 매크로는 여전히 입력 - 선택되어 있는지, 그래서 컴파일러가 사전에 x의 유형을 알고 싶어하기 때문에 난 그냥

reify(foo(x.splice)) 

을 말할 수 없습니다. 필자는 스칼라 매크로를 처음 사용하는 것에 대해 새롭다 (그리고 그것은 실질적인 API이다).

매크로없이이 코드를 레이아웃하는 방법이 있다면 도움이 될 것입니다.

+3

매크로를 사용하면이 작업을 수행 할 수 있지만, 실제로는 그리 좋은 생각이 아닙니다. (그리고 나는 스칼라의 매크로 시스템의 팬입니다.) 대신 형식 클래스를 사용하십시오. –

+0

네, 타입 클래스는 깔끔한 아이디어입니다. 그래도 매크로로 할 수있는 방법이 있다면 (교육적 목적으로) 궁금합니다. 가능한 것처럼 보입니다. – geoffliu

답변

1

문제를 다르게 해결할 수 있습니다.

유형 대신 A or B 유형에서 원하는 것을 생각하십시오. 귀하의 예를 들어 말하면 충분할 것입니다 : "그것이 어떤 형태인지는 중요하지 않습니다. 내가 그것에 대해 foo 방법을 가지고있는 한." 그 코드는 다음과 같습니다 :

trait FooMethod[T] { 
    def apply(t:T):C 
} 

object FooMethod { 
    implicit val forA = new FooMethod[A] { 
    def apply(a:A):C = foo(a) 
    } 

    implicit val forB = new FooMethod[B] { 
    def apply(b:B):C = foo(b) 
    } 
} 

def bar[X](x: X)(implicit foo:FooMethod[X]) = { 
    val c = foo(x) 
    // Code that works with c 
}