Considere la siguiente definición de una categoría:de orden superior ScalaCheck
trait Category[~>[_, _]] {
def id[A]: A ~> A
def compose[A, B, C](f: A ~> B)(g: B ~> C): A ~> C
}
He aquí un ejemplo para las funciones unarios:
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)
}
}
Ahora, las categorías están sujetos a algunas leyes. composición relativa (.
) y la identidad (id
):
forall f: categoryArrow -> id . f == f . id == f
que quieren probar esto con ScalaCheck. Vamos a tratar de funciones sobre los números enteros:
"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) }
}
}
Pero éstas se han cuantificado más de (i) un tipo específico (Int
), y (ii) una función específica (intG
). Así que aquí está mi pregunta: ¿hasta dónde puedo llegar en términos de generalizar las pruebas anteriores, y cómo? O, en otras palabras, ¿sería posible crear un generador de funciones arbitrarias A => B
y proporcionarlas a ScalaCheck?
No sé la respuesta exacta a su pregunta, pero me recuerda los controles de las leyes de mónada en scalaz. Tal vez pueda inspirarse en https://github.com/scalaz/scalaz/blob/master/tests/src/test/scala/scalaz/MonadTest.scala –
quizás http://stackoverflow.com/users/53013/daniel -c-sobral sabe la respuesta? –
Si el tipo se elige arbitrariamente, puede ver esto como una cuantificación universal a través del épsilon de Hilbert. Ver https://gist.github.com/2659013. –