필자는 Hilbert의 엡실론을 정확히 모르는 상태에서 ScalaCheck의 Arbitrary
과 Gen
을 사용하여 사용할 함수를 선택했습니다.
먼저 생성하려는 함수의 기본 클래스를 정의하십시오. 일반적으로 정의되지 않은 결과 (예 : 0으로 나누기)가있는 함수를 생성 할 수 있으므로 PartialFunction
을 기본 클래스로 사용합니다.
trait Fn[A, B] extends PartialFunction[A, B] {
def isDefinedAt(a: A) = true
}
이제 몇 가지 구현을 제공 할 수 있습니다. toString
을 무시하면 ScalaCheck의 오류 메시지를 알 수 있습니다.
object Identity extends Fn[Int, Int] {
def apply(a: Int) = a
override def toString = "a"
}
object Square extends Fn[Int, Int] {
def apply(a: Int) = a * a
override def toString = "a * a"
}
// etc.
나는 생성자에 추가 인수를 전달하는 경우 클래스를 사용하여 바이너리 기능에서 단항 함수를 생성하기 위해 선택했습니다. 그것을 할 수있는 유일한 방법은 아니지만 가장 간단합니다.
case class Summation(b: Int) extends Fn[Int, Int] {
def apply(a: Int) = a + b
override def toString = "a + %d".format(b)
}
case class Quotient(b: Int) extends Fn[Int, Int] {
def apply(a: Int) = a/b
override def isDefinedAt(a: Int) = b != 0
override def toString = "a/%d".format(b)
}
// etc.
이제 Fn[Int, Int]
의 발전기를 만들고 암시 Arbitrary[Fn[Int, Int]]
으로 그것을 정의 할 필요가있다. 얼굴이 파란색이 될 때까지 발전기를 계속 추가 할 수 있습니다 (다항식, 간단한 함수로 구성된 복잡한 함수 작성 등).
val funcs = for {
b <- arbitrary[Int]
factory <- Gen.oneOf[Int => Fn[Int, Int]](
Summation(_), Difference(_), Product(_), Sum(_), Quotient(_),
InvDifference(_), InvQuotient(_), (_: Int) => Square, (_: Int) => Identity)
} yield factory(b)
implicit def arbFunc: Arbitrary[Fn[Int, Int]] = Arbitrary(funcs)
이제 속성을 정의 할 수 있습니다. 정의되지 않은 결과를 피하려면 intG.isDefinedAt(a)
을 사용하십시오. 제가 보여준 것은 단지 테스트 기능을 일반화하는 동안
property("left identity simple funcs") = forAll { (a: Int, intG: Fn[Int, Int]) =>
intG.isDefinedAt(a) ==> (fCat.compose(fCat.id[Int])(intG)(a) == intG(a))
}
property("right identity simple funcs") = forAll { (a: Int, intG: Fn[Int, Int]) =>
intG.isDefinedAt(a) ==> (fCat.compose(intG)(fCat.id)(a) == intG(a))
}
는 희망이 당신에게 유형에 걸쳐 일반화 선진 형 시스템 속임수를 사용하는 방법에 대한 아이디어를 줄 것이다.
귀하의 질문에 대한 정확한 답변을 모르겠지만 그것은 scalaz의 모나드 법에 대한 수표를 상기시켜줍니다. 아마 https://github.com/scalaz/scalaz/blob/master/tests/src/test/scala/scalaz/MonadTest.scala –
에서 영감을 얻을 수 있습니다. http://stackoverflow.com/users/53013/daniel -c-sobral이 답을 알고 있습니까? –
유형을 임의로 선택한 경우 힐버트의 엡실론을 통해 보편적 인 부량으로 볼 수 있습니다. https://gist.github.com/2659013을 참조하십시오. –