2017-10-13 20 views
2

リスト内の値を合計する汎用関数が必要です。数値のスカラ和のリスト

次のコードはコンパイルされません:

def sum[T : Numeric](x: List[T]): T = { 
    if(x.isEmpty) 0 
    else x.head + sum(x.tail) 

    } 

をコンパイルエラーがある:

error: type mismatch; 

[INFO] found : Int(0) 

[INFO] required: T 

[INFO]  if(x.isEmpty) 0 
+0

:)合計値ITALさもなければfold操作を使用インスタンスが定義されていますか? –

+0

私はオンラインでコードスニップに遭遇し、どのようにしてより一般的にすることができるのか不思議でした。スカラを理解するためのエクササイズです(私は学校にいない、ちょっと好奇心が強いです) – Jake

+1

ところで、このタイプの関数に気をつけなければならないことの1つは、_tail recursive_ではありません。あなたが非常に長いリストを持っているなら、_stackオーバーフロー_を得ることができます。 (ここで、前にその式を聞いたことがありますか?)関数をテール再帰的にするには、再帰呼び出しを最後の式にする必要があります。 –

答えて

4

このエラーは、あなたが戻り値の型がTで指定した、しかし、あなたがしていることを語っています空リストの場合はいつも0を返します。これはIntです。渡されたリストに何か他のものが含まれている場合、つまりTDoubleまたはカスタムタイプですか?あなたがしたくない場合は

def sum[T](x: List[T])(implicit num: Numeric[T]): T = x.foldLeft(num.zero)(num.plus) 
+0

あなたは暗黙のうちに[Numeric [T]]。plus'また! ;) –

+0

はい、そうでなければそうです:エラー:型の不一致; [INFO]が必要です:リスト[String] [INFO] else x.head + sum(x.tail) – Jake

+0

「暗黙のうちにシンボルを解決できません」 – Jake

2

if(x.isEmpty) implicitly[Numeric[T]].zero 

完全な加工方法:

def sum[T : Numeric](x: List[T]): T = { 
    if (x.isEmpty) implicitly[Numeric[T]].zero 
    else implicitly[Numeric[T]].plus(x.head, sum(x.tail)) 
} 

それともこれを試してみてくださいセットアップするなぜだけ `x.sum`( 'X'が '一覧で[T]を`使用し、' T 'は、暗黙の `数値[T]を有していない

def sumWithReduce[T](lst: List[T])(implicit numericType: Numeric[T]):T 
= lst.reduce(numericType.plus) 

def sumWithFold[T](lst: List[T])(implicit numericType: Numeric[T]):T 
= lst.fold(numericType.zero)(numericType.plus) 
1

使用reduce(:これを試してみてください

def sum[T](x: List[T])(implicit num: Numeric[T]): T = { 
    import num._ 
    if (x.isEmpty) zero 
    else x.head + sum(x.tail) 
} 
+0

'reduce'は空リストでは失敗し、' fold'はもっと頑強です。 –