2011-01-13 18 views
5

Vorrei convertire implicitamente tra l'oggetto Elem XML di Scala e un'altra rappresentazione di un elemento XML, nel mio caso dom4j Element. Ho scritto le seguenti conversioni implicite:Conversione implicita tra tipi di collezione Scala

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

Fin qui tutto bene, questo funziona.

Ora ho bisogno anche di raccolte di detti elementi per convertire entrambi i modi. Per prima cosa, devo assolutamente scrivere metodi di conversione aggiuntivi? Le cose non sembra funzionare se non l'avessi fatto.

ho cercato di scrivere il seguente:

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

Questo non sembra troppo ideale, perché se il metodo di conversione prende un Traversable, poi ritorna anche una Traversable. Se passo una lista, ottengo anche un Traversable. Quindi presumo che la conversione dovrebbe essere parametrizzata in qualche modo.

Quindi qual è il modo standard di scrivere queste conversioni per essere il più generico possibile?

risposta

1

Penso che questo potrebbe richiedere implicitamente troppo. Tanto più che si può semplicemente utilizzare il metodo convertitore in una mappa

val listOfElements = listOfElems map elemToElement(_) 

Penso che la concisione livello si sta andando per è sempre in confusione. Creerei un convertitore e lavorerò solo in una delle rappresentazioni in modo da evitare che le cose si confondano.

+0

Perché è più confuso essere in grado di convertire automaticamente da 'X' a' Y' che da 'Lista [X]' a 'Lista [Y]'? Riempie esattamente lo stesso bisogno, cioè che non ti interessa realmente quale sia la rappresentazione usata e vuoi che il compilatore gestisca il lavoro occupato per te. –

+0

È in gran parte una questione di stile e buone pratiche. Chiedere implicitamente al lavoro che molta magia sta chiedendo guai. Sono, a mio avviso, uno dei BFG di scala: fai attenzione a cosa lo indicherai. – sblundy

+0

Sono d'accordo con Rex: non sono d'accordo sul fatto che sia confuso. Al contrario, avrei persino sperato che la definizione di una conversione implicita di un determinato tipo implicasse automaticamente la conversione implicita (diciamo anche "monadica") di contenitori per quel tipo di lavoro. – ebruchez

2

Questo non è banale, quindi per ottenere quello che vuoi penso che dovrai andare un po 'più a fondo. Questo articolo spiega molto su come funzionano le collezioni scala (e interessante anche leggere): http://www.artima.com/scalazine/articles/scala_collections_architecture.html

Stai praticamente provando a fare lo stesso di List.map (...) (o TraversableLike che ha l'implementazione) e metodi simili .... solo con la conversione implicita in aggiunta.

Aggiornamento:

ho iniziato a sperimentare un po 'con questo e ha scritto una conversione in base a quello che fa TraversableLike.map (...). Tuttavia ho scoperto che ha funzionato anche senza di esso. Sembra Scala supporta fuori dalla scatola (almeno sulla mia macchina :-)):

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/>) 

Questo era quello che erano dopo?

+0

Grazie per il puntatore, ho effettivamente esaminato quel documento qualche tempo fa, ma speravo in una risposta diretta alla mia domanda. #laziness – ebruchez

+0

Wow, il tuo esempio funziona nel REPL!Ora la domanda è perché non ha funzionato nel contesto del mio codice. Sospetto che sia perché sto passando una lista Scala [Elem] a un metodo che richiede java.util.List [Element]. La "Regola" una volta per volta "si avvia, viene tentata solo una conversione implicita. Guardando più dentro. – ebruchez

+0

Mmh, quindi non funziona quando si chiamano le funzioni: 'def fa (p: List [Element]) {}; errore fa (b) '>: tipo mancata corrispondenza – ebruchez

Problemi correlati