我有一個數值求解功能(Double => Double
),我試圖聰明,並使用Numeric[T]
保持兩種數字分開。斯卡拉數字問題[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])
參數,但未能有兩個這樣的(都爲A
和B
)。
以下是編譯器說的話(斯卡拉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
感謝您的任何想法。
準確。謝謝。而且我甚至可以使用正常的操作員!我的原始代碼中有一個錯誤:「 - newStep」應該是「+ newStep」(使得結果更快)。 – akauppi