2011-01-13 6 views
5

내 경우 dom4j 요소에서 Scala XML Elem 객체와 XML 요소의 다른 표현 사이를 암시 적으로 변환하고 싶습니다. 나는 다음과 같은 암시 적 변환을 썼다 :Scala 컬렉션 유형 간의 암시 적 변환

implicit def elemToElement(e: Elem): Element = ... do conversion here ... 
implicit def elementToElem(e: Element): Elem = ... do conversion here ... 

지금까지 그렇게 좋았다.

이제 두 요소를 변환하기 위해 상기 요소의 콜렉션이 필요합니다. 첫째, 추가 변환 방법을 반드시 작성해야합니까? 내가하지 않으면 상황이 작동하지 않는 것 같습니다. 변환 방법은에 이동 걸린다면, 그것은 또한에 이동을 반환하기 때문에

implicit def elemTToElementT(t: Traversable[Elem]) = t map (elemToElement(_)) 
implicit def elementTToElemT(t: Traversable[Element]) = t map (elementToElem(_)) 

이 너무 이상적 보이지 않는 :

나는 다음과 같은 작성했습니다. List를 통과하면 Traversable도 나옵니다. 그래서 저는 변환이 어떻게 든 매개 변수 화되어야한다고 가정합니다.

가능한 한 일반적인 것으로 만들기 위해 이러한 변환을 작성하는 표준 방법은 무엇입니까?

답변

1

나는 이것이 너무 함축적이라고 생각합니다. 그냥지도

val listOfElements = listOfElems map elemToElement(_) 

의 변환 방법을 사용할 수 있습니다, 특히 당신이 가고있는 수준의 간결함이 난처에지고 있다고 생각합니다. 나는 컨버터 레이어를 만들고 표현 중 하나에서만 작업하여 혼란스러워 지도록합니다.

+0

'List [X]'에서'List [Y]'로 자동 변환하는 것이 왜 더 이상 혼란 스럽습니까? 이것은 정확히 동일한 요구를 채 웁니다. 즉, 어떤 표현이 사용되는지에 대해 실제로 신경 쓰지 않고 컴파일러가 당신을 위해 바쁜 일을 처리하기를 원합니다. –

+0

크게 스타일과 모범 사례의 문제입니다. 많은 마술이 문제를 요구하고 있다는 것을 함축적으로 요구하십시오. 저의 견해에 따르면, 그들은 스칼라의 BFG 중 하나입니다 : 당신이 가리키는 것을주의하십시오. – sblundy

+0

나는 Rex와 동의한다. 나는 그것이 혼란 스럽다는 것에 동의하지 않는다. 반대로, 주어진 유형의 암시 적 변환을 정의하면 자동으로 해당 유형의 컨테이너 ("모나 딕 (monadic)"이라고 함)의 암시 적 변환도 자동으로 이루어지기를 기대했을 것입니다. – ebruchez

2

이것은 매우 사소한 것이므로 원하는 것을 얻으려면 조금 더 깊이 들어가야 할 것입니다. 이 기사에서는 스칼라 컬렉션이 어떻게 작동하는지에 대해 많이 설명합니다. 또한 http://www.artima.com/scalazine/articles/scala_collections_architecture.html

기본적으로 List.map (...) (또는 구현이있는 TraversableLike)과 동일한 작업을 수행하려고합니다.) 및 이와 유사한 방법 .... 또한 암시 적 변환을 통해서만 가능합니다.

업데이트 :이와 약간의 실험을 시작 TraversableLike.map (...)가 무엇을 기반으로 변환을 썼다

. 그러나 나는 그것이 그것 없이도 효과가 있다는 것을 발견했다. 스칼라처럼 보인다는 (적어도 내 기계 :-))에 상자 밖으로 지원 :이 후 무엇인지

case class Element(e: Elem) 
implicit def elemToElement(e: Elem): Element = Element(e) 
implicit def elementToElem(e: Element): Elem = e.e 

val a: List[Element] = List(<a/>, <b/>, <c/>) 
val b: List[Elem] = List(Element(<a/>), Element(<b/>), Element(<c/>)) 
val c: Set[Element] = Set(<a/>, <b/>, <c/>) 

입니까?

+0

포인터를 주셔서 감사합니다. 실제로 그 문서를 조금 전에 읽었지만 제 질문에 대한 직접적인 대답을 기대했습니다. #laziness – ebruchez

+0

와우, 당신의 예가 REPL에서 작동합니다!이제 문제는 내 코드의 컨텍스트에서 작동하지 않는 이유입니다. 스칼라리스트 [Elem]을 java.util.List [Element]가 필요한 메소드에 전달했기 때문에 그것이 의심 스럽습니다. "한 번에 하나의 규칙"이 실행되면 암시 적 변환은 하나만 시도됩니다. 그것에 대해 더 많이 보아라. – ebruchez

+0

Mmh, 그래서 함수를 호출 할 때 작동하지 않습니다 :'def fa (p : List [Element]) {}; fa (b)'> 오류 : 형식이 일치하지 않습니다. – ebruchez