2011-01-13 19 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(_)) 

変換方法はTraversableのを取る場合、それはまた、Traversableのを返すので、これはあまりにも理想的では見えません。リストに合格すれば、Traversableも出ます。だから私は変換が何らかの形でパラメータ化されるべきだと考えています。

できるだけ一般的にするためにこれらのコンバージョンを作成する標準的な方法は何ですか?

答えて

1

私は、これはあまりにも遠慮しているかもしれないと思います。あなただけのマップ

val listOfElements = listOfElems map elemToElement(_) 

に変換方法を使用することができます。特に、私はあなたのために行っているレベルの簡潔さは、難読化になっていると思います。私はコンバータレイヤーを作成し、表現が混乱しないように表現のうちの1つのみで作業します。

+0

なぜ 'X'から' Y'に 'List [X]'から 'List [Y]'に自動的に変換できないのでしょうか?これはまったく同じ必要性を満たします。つまり、どの表現が使用されているのか、コンパイラがあなたのために忙しい作業を処理することを実際に気にしないことです。 –

+0

これは主にスタイルとベストプラクティスの問題です。多くの魔法が問題を求めていることを暗黙のうちに尋ねる。彼らは、私の見解では、スカラーのBFGの1つです:あなたが指しているものに注意してください。 – sblundy

+0

私はRexと同意する:私はそれが紛らわしいことに同意しない。逆に、与えられた型の暗黙の変換を定義すると、自動的にその型のコンテナ(暗黙的に "モナド"という)のコンテナも変換されることを期待していました。 – ebruchez

2

これは自明ではないので、あなたが望むものを得るためには、少し深めにしなければならないと思います。この記事では、スカラーコレクションの仕組みについて説明します(http://www.artima.com/scalazine/articles/scala_collections_architecture.html

)あなたは基本的にList.map(...)(または実装を持つTraversableLike )と同様の方法....だけでなく、暗黙的な変換を追加します。

アップデート:私はこれで少し実験を始めとTraversableLike.map(...)は何をするかに基づいて変換を書いた

。しかし、私はそれがなくても働くことを発見しました。 Scalaが(少なくとも私のマシンで:-)それをサポートしているようです:

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で動作します!問題はなぜ自分のコードの文脈ではうまくいかないのかということです。 Scala List [Elem]をjava.util.List [Element]を必要とするメソッドに渡しているからです。 「1度に1つのルール」が開始され、暗黙の変換が1回だけ試行されます。それをもっと見る。 – ebruchez

+0

Mmhなので、関数を呼び出すときには動作しません: 'def fa(p:List [Element]){}; fa(b) '>エラー:型の不一致 – ebruchez