数値解法関数 ( ) があり、2 種類の数値を区別Double => Double
するために巧妙に使用しようとしました。Numeric[T]
これは簡単なことではありませんでした。残りの問題は次のとおりです。
- 割り算のやり方;
Numeric[T]
プラス、マイナスなどの演算子のみがあります。 - コンパイラが関数を見つけられない理由
implicit evidence$1: Numeric[Double]
(以下のコンパイラ出力を参照)
理想的には、「A
とB
は両方Double
ですが、それらを混ぜ合わせたら教えてください」と言いたいです。
コードは次のとおりです。
import scala.annotation.tailrec
class Sweep[A: Numeric, B: Numeric]( fDiff: A => B, initialSeed: A, initialStep: A, bEps: B )
{
val anum= evidence$1
val bnum= evidence$2
assert( anum.signum(initialStep) > 0 )
assert( bnum.lt( fDiff(initialSeed), fDiff( anum.plus(initialSeed,initialStep) )) ) // check that it's an increasing function
@tailrec
private def sweep( seed: A, step: A ): A = {
val bDiff= fDiff(seed)
if ( bnum.lt( bnum.abs(bDiff), bEps) ) { // done
seed
} else if ( bnum.signum(bDiff) != anum.signum(step) ) {
sweep( anum.plus(seed,step), step ) // continue, same step and direction ('bDiff' should go smaller)
} else {
val newStep = anum.toDouble(step) / -2.0
sweep( anum.minus(seed,newStep), newStep ) // reverse, smaller step
}
}
// Make sure we take the initial step in the right direction
//
private lazy val stepSign= -bnum.signum( fDiff(initialSeed) )
def apply: A = sweep( initialSeed, stepSign * initialStep )
}
object TestX extends App {
val t= new Sweep( (a: Double) => (a*a)-2, 1.0, 0.5, 1e-3 )()
println( t, math.sqrt(2.0) )
}
(implicit anum: Numeric[A])
古いパラメーターでも試してみましたが、そのような2つ( forA
との両方B
)を持つことができませんでした。
コンパイラが言うことは次のとおりです(Scala 2.9):
fsc -deprecation -d out-make -unchecked src/xxx.scala
src/xxx.scala:25: error: type mismatch;
found : newStep.type (with underlying type Double)
required: A
sweep( anum.minus(seed,newStep), newStep ) // reverse, smaller step
^
src/xxx.scala:33: error: overloaded method value * with alternatives:
(x: Double)Double <and>
(x: Float)Float <and>
(x: Long)Long <and>
(x: Int)Int <and>
(x: Char)Int <and>
(x: Short)Int <and>
(x: Byte)Int
cannot be applied to (A)
def apply: A = sweep( initialSeed, stepSign * initialStep )
^
src/xxx.scala:38: error: not enough arguments for constructor Sweep: (implicit evidence$1: Numeric[Double], implicit evidence$2: Numeric[Double])Sweep[Double,Double].
Unspecified value parameters evidence$1, evidence$2.
val t= new Sweep( (a: Double) => (a*a)-2, 1.0, 0.5, 1e-3 )()
^
three errors found
アイデアをありがとう。