2013-11-01 2 views
2

나는 다음과 같은 일반적인 탐색 기능을 작성하는 Shapeless library에서 SYB 구현을 사용하려면 :셰이프가있는 스칼라의 구조 프로그래밍 : SYB 구현을 올바르게 사용하는 방법?

class Data 

// Perform the desired manipulation on the given data 
object manipulate extends ->((data: Data) => data) 

def traverseAndManipulate[B](expr: B): B = { 
    everywhere(manipulate)(expr) 
} 

불행하게도,이 코드는 (볼품 2.0.0-M1 및 스칼라 2.10.2를 사용하여) 다음과 같은 유형의 오류가 발생을 :

type mismatch; 
[error] found : shapeless.EverywhereAux[SYB.manipulate.type] 
[error] required: ?{def apply(x$1: ? >: B): ?} 
[error] Note that implicit conversions are not applicable because they are ambiguous: 
[error] both method inst1 in trait PolyInst of type [A](fn: shapeless.Poly)(implicit cse: fn.ProductCase[shapeless.::[A,shapeless.HNil]])A => cse.Result 
[error] and macro method apply in object Poly of type (f: Any)shapeless.Poly 
[error] are possible conversion functions from shapeless.EverywhereAux[SYB.manipulate.type] to ?{def apply(x$1: ? >: B): ?} 
[error]  everywhere(manipulate)(expr) 

나는 어떤 방법으로 제한 할 필요가 B 유형 매개 변수의 볼품 라이브러리의 암시 적 매크로를 적용 할 것을, 가정,하지만 난 방법을 모르겠어요.

Shapeless를 사용하여 이러한 순회 기능을 작성할 수 있습니까?

답변

3

당신은 어디서나 당신의 방법의 몸에서 사용할 수있는 연결자에 대한 암시 적 증거를 만들기 위해

def traverseAndManipulate[B](expr: B) 
    (implicit e: Everywhere[manipulate.type, B]) = everywhere(manipulate)(expr) 

주의를 필요로하는 traverseAndManipulate을주고 나는 순간에 단지 추측 할 수 아니에요 이유에 대한 명시 적 결과 유형 B은 컴파일러가 유사한 모호성을보고하게합니다. 그러나 결과 유형은 B으로 올바르게 추론됩니다. 명시적인 결과 유형을 사용하려면 다음과 같아야합니다.

def traverseAndManipulate[B](expr: B) 
    (implicit e: Everywhere[manipulate.type, B] { type Result = B }): B = e(expr)