2011-06-18 17 views
6

私はリスト[番号]を持っています。 Number - Int、Doubleなどの異なるサブクラスの値を含みます。私はすべての値を合計したい。リストにIntのみが含まれている場合、結果はIntであることを望みます。ミックスがある場合は、通常のScalaの規則に従いたいと思います。Int + Double = Double(など)。数字を一緒に追加する

私はこれを試してみた:

val result = list.reduceLeft(_ + _) 

これもコンパイルではありません。 Numberには別のNumberをとる+メソッドが定義されていません。

どうすればこの問題を解決できますか? Doubleのリストを減らすことにより

アンドレス

+1

、依頼するより良い形を検討しています。 Scalaのメーリングリストの_or_ StackOverflowに質問があります。両方ともではありません。 lar、StackOverflowは、他の人が質問と回答から学ぶ方がメーリングリストのアーカイブよりも簡単なので、通常はより良い選択です! –

+1

私は訂正しました。二度と起こらない。すべての助けに感謝し、私にネチケットを教えることにとても優しいことに感謝します。 – Andres

答えて

9

質問:

Numberは、Javaクラスで、プリミティブ型に自分自身を変換別に何の機能を持っていません。残念ながら、ScalaのAnyValは、プリミティブ型をマークする以外に何もしません.ScalaのNumeric[T]は、型の組み合わせではなく、独自の型しか知りません。

かなり不快なパターンマッチングが残っています。最短構文あなたが唯一のダブル、int型を処理するために持っていることを確認している場合である:私は私たちのためにアンボクシングを行うにはScalaのパターンマッチを取得するためにAnyにキャストしてい

list.reduceLeft((l,r) => (l: Any, r: Any) match { 
    case (li: Int, ri: Int) => li + ri 
    case _ => l.doubleValue + r.doubleValue 
}) 

注意。あなたがNumberとして残しておけば、java.lang.IntegerでパターンマッチしてからvalueOfにする必要があります。これは痛みです。

あなたはもっとしたい場合は、適切なプロモーションに構築する必要があります:

list.reduceLeft((l,r) => (l: Any) match { 
    case li: Int => (r: Any) match { 
    case ri: Int => li + ri 
    case rf: Float => li + rf 
    case rl: Long => li + rl 
    case _ => li + r.doubleValue 
    } 
    case lf: Float => /* etc. */ 
}) 

あなたは少しよりも、この多くを行う必要がある場合、あなたはおそらく、あなた自身の賛成でNumericを放棄する方がいいでしょう適切なプロモーションと共に自分自身を追加する方法を知っているラッパークラス。あなたは一度一致するパターンを書くことができ、あなたのリストの中で+を使うことに戻ることができます。

sealed abstract class Addable { 
    def +(a: Addable): Addable 
} 

final case class MyInt(value: Int) extends Addable { 
    def +(a: Addable) = a match { 
    case MyInt(i) => MyInt(value + i) 
    case MyFloat(f) => MyFloat(value + f) 
    ... 
    } 
} 

final case class MyFloat(value: Float) extends Addable { 
    def +(a: Addable) = a match { 
    case MyInt(i) => MyFloat(value + i) 
    ... 
    } 
} 

... 

この方法の一つのわずかな利点は、あなたが(値に標準とは異なる方法を促進するために、たとえば、あなたが長い=ダブル、フロートが実際にカットされていないので、出ているフロート+を決めるかもしれません決めることができるということです。例えば、長い間の数値精度の多くを維持し、MyDouble(value.toDouble + f.toDouble)を行うために

をそれはすべてかなり厄介だ。JavaのもScalaのどちらが本当に混在型数学のサポートを提供し、将来の参考のため

0

を。

クラスNumberを使用しないでください。実際には何もできません。 Scalaクラスでもなく、Javaクラスです。質問が最初だったScalaのメーリングリストから私の答えをコピー

+0

私はなぜあなたがdownvotedされているのだろうか。 'num.view.map(_。doubleValue).sum'のようなことはここでは妥当です。 – soc

+0

@SOC私はしましたか?恐らくそれは間違いでした。私は投票を断念することができません、私はここでまだ比較的新しいです。 –