I would like to implicitly convert between the Scala XML Elem object and another representation of an XML element, in my case dom4j Element. I wrote the following implicit conversions:
implicit def elemToElement(e: Elem): Element = ... do conversion here ...
implicit def elementToElem(e: Element): Elem = ... do conversion here ...
So far so good, this works.
Now I also need collections of said elements to convert both ways. First, do I absolutely need to write additional conversion methods? Things didn't seem to work if I didn't.
I tried to write the following:
implicit def elemTToElementT(t: Traversable[Elem]) = t map (elemToElement(_))
implicit 开发者_JAVA百科def elementTToElemT(t: Traversable[Element]) = t map (elementToElem(_))
This doesn't look too ideal because if the conversion method takes a Traversable, then it also returns a Traversable. If I pass a List, I also get a Traversable out. So I assume the conversion should be parametrized somehow.
So what's the standard way of writing these conversions in order to be as generic as possible?
This is non-trivial so in order get what you want I think you'll have to go a bit deeper. This article explains a lot about how the scala collections work (and interesting read it is too): http://www.artima.com/scalazine/articles/scala_collections_architecture.html
You're basically trying to do the same as List.map(...) (or TraversableLike which has the implementation) and similar methods.... only with implicit conversion in addition.
Update:
I started experimenting a little bit with this and wrote a conversion based on what TraversableLike.map(...) does. However I discovered that it worked even without it. Seems like Scala supports it out of the box (at least on my machine :-) ):
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/>)
This was what you were after?
I think this might be taking implicits too far. Especially as you can just use the converter method in a map
val listOfElements = listOfElems map elemToElement(_)
I think that the level conciseness you're going for is getting into obfuscation. I would create a converter layer and work in only one of the representations so as to keep things from getting to confused.
精彩评论