スカラ型のシステムで遊んでいて、もう一度私はそれと戦っているのです。私はいくつかのシンプルなグラフィックスアプリケーション用のVectorライブラリを作成しました。scala higher種類とscalatic equalality
今、私はscalacheckとscalatestを使ってVectorプロパティをテストしたいと思っています。私が直面している問題は、倍精度または浮動小数点数を使用するときにベクトルの等価性をチェックすることは、思ったほど簡単ではないということです。今私は、テストフレームワークで最も慣用的な方法は、私のベクトルクラスのnew Equality
を作成することであることを考え出しました。しかし、背中のステップと私のベクトルdefenitionsまた、ここで適用を解除する図示していない
abstract class Vec[T, V[T] <: Vec[T, V]](val elems: T*)(implicit num: VecIntegral[T], factory: VecFactory[V])
class Vec2[T](x: T, y: T)(implicit num: VecIntegral[T]) extends Vec[T, Vec2](x,y)
Vec3[T](x: T, y: T, z: T)(implicit num: VecIntegral[T]) extends Vec[T, Vec3](x,y, z)
を見てみると、パターンマッチングなどを可能にVecとオブジェクトのために定義されて適用できます。
は、だから今テストを書くための私の最初の試みは、この
abstract class VecSuite[T: Arbitrary, V[T] <: Vec[T, V]](implicit genVec: Arbitrary[V[T]], num: VecIntegral[T])
extends PropSpec with PropertyChecks {
import num._
property("associative add") {
forAll { (a: V[T], b: V[T]) =>
assert((a + b).===(b + a))
}
}
property("scalar distributed") {
forAll { (a: V[T], b: V[T], s: T) =>
assert((a + b) * s === a * s + b * s)
}
}
...
}
class Vec2IntSuite extends VecSuite[Int, Vec2]
class Vec2FloatSuite extends VecSuite[Float, Vec2]
class Vec2DoubleSuite extends VecSuite[Double, Vec2]
class Vec2LongSuite extends VecSuite[Long, Vec2]
ようになります。ここで再び、私はショーをいけないが、私はVec2[T]
とVec3[T]
のクラスの実装暗黙の工場があります。
これは本当にうまくいきます。 Float
とDouble
の場合、丸め誤差が発生し、等価チェックが爆発するという点を除いて、一般的なテストを書いて、サポートされているすべての異なるVector実装に適用できます。
だから今、私は私だけDouble
とFloat
のための2つの暗黙の値の試行を必要とするようにVec2
とVec2
の間で、それは一般的にしようとしてEquality
クラスで遊んで開始します。
implicit val doubleEq = new Equality[ V[Double] forSome{ type V[Double] <: Vec[Double, V] }] {
override def areEqual(a: V[Double] forSome {type V[Double] <: Vec[Double, V]}, b: Any): Boolean = (a,b) match {
case (lhs: Vec[Double, _], rhs: Vec[Double, _]) => lhs.elems.zip(rhs.elems).forall {case (e1, e2) => e1 === e2 +- 0.01d }
case _ => false
}
}
しかし、これは座っていません。コンパイラでうまくいけば、それはjava.lang.StackOverflowException
で爆発する。
は、それがVec2
かVec3
であれば、それは暗黙のうちに私のテストケースで使用されるようにEquality
の種類を書くのいずれかの方法がある限り、それはタイプDouble
であるよう関わらずありますか?