カテゴリの次の定義を検討してください。
trait Category[~>[_, _]] {
def id[A]: A ~> A
def compose[A, B, C](f: A ~> B)(g: B ~> C): A ~> C
}
単項関数の例を次に示します。
object Category {
implicit def fCat = new Category[Function1] {
def id[A] = identity
def compose[A, B, C](f: A => B)(g: B => C) = g.compose(f)
}
}
現在、カテゴリはいくつかの法律の対象となっています。構成 ( .
) と同一性 ( id
) の関連付け:
forall f: categoryArrow -> id . f == f . id == f
これを ScalaCheck でテストしたい。整数に対する関数を試してみましょう:
"Categories" should {
import Category._
val intG = { (_ : Int) - 5 }
"left identity" ! check {
forAll { (a: Int) => fCat.compose(fCat.id[Int])(intG)(a) == intG(a) }
}
"right identity" ! check {
forAll { (a: Int) => fCat.compose(intG)(fCat.id)(a) == intG(a) }
}
}
しかし、これらは (i) 特定のタイプ ( Int
)、および (ii) 特定の機能 ( intG
) について定量化されます。ここで私の質問があります: 上記のテストを一般化するという点で、どこまで行くことができますか? あるいは、言い換えれば、任意のA => B
関数のジェネレーターを作成して、それらを ScalaCheck に提供することは可能でしょうか?