Tuesday, May 22, 2012

High-Order ScalaCheck

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