Betrachten Sie die folgende Definition einer Kategorie:hohe Ordnung Scalacheck
trait Category[~>[_, _]] {
def id[A]: A ~> A
def compose[A, B, C](f: A ~> B)(g: B ~> C): A ~> C
}
Hier ist ein Beispiel für einstellige Funktionen:
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)
}
}
Nun Kategorien unterliegen einige Gesetze. Im Zusammenhang Zusammensetzung (.
) und Identität (id
):
forall f: categoryArrow -> id . f == f . id == f
Ich möchte dies testen, mit Scalacheck. Lassen Sie uns versuchen, für Funktionen über ganze Zahlen:
"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) }
}
}
Diese aber sind quantifiziert über (i) einen bestimmten Typ (Int
) und (ii) eine spezifische Funktion (intG
). Also, hier ist meine Frage: Wie weit kann ich in Bezug auf die Verallgemeinerung der oben genannten Tests gehen, und wie? Oder mit anderen Worten, wäre es möglich, einen Generator von beliebigen A => B
Funktionen zu erstellen und diese an ScalaCheck zu liefern?
Ich weiß nicht die genaue Antwort auf Ihre Frage, aber es erinnert mich an die Überprüfung der Monaden Gesetze in Scalaz. Vielleicht können Sie Inspiration von https://github.com/scalaz/scalaz/blob/master/tests/src/test/scala/scalaz/MonadTest.scala –
vielleicht http://stackoverflow.com/users/53013/daniel nehmen -c-sbral kennt die Antwort? –
Wenn der Typ willkürlich gewählt wird, könnte man dies als universelle Quantifizierung über Hilberts Epsilon betrachten. Siehe https://gist.github.com/2659013. –