Consider the following definition of a category:
trait Category[~>[_, _]] {
def id[A]: A ~> A
def compose[A, B, C](f: A ~> B)(g: B ~> C): A ~> C
}
Here's an instance for unary functions:
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)
}
}
Now, categories are subject to some laws. Relating composition (.
) and identity (id
):
forall f: categoryArrow -> id . f == f . id == f
I want to test this with ScalaCheck. Let's try for functions over integers:
"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) }
}
}
But these are quantified over (i) a specific type (Int
), and (ii) a specific function (intG
). So here's my question: how far can I go in terms of generalizing the above tests, and how? Or, in other words, would it be possible to create a generator of arbitrary A => B
functions, and provide those to ScalaCheck?
No comments:
Post a Comment