我有一个数值求解函数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])
参数,但无法拥有两个这样的参数(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
感谢您的任何想法。