如何在 scalacheck 中为自定义列表定义任意值?
How to define an arbitrary for a custom list in scalacheck?
我定义了一个自定义列表并想用 scalacheck 测试它:
sealed trait MyList[+A] {
def flatMap[B](f: A => MyList[B]): MyList[B]
def map[B](f: A => B): MyList[B]
}
case object MyNil extends MyList[Nothing] {
override def flatMap[B](f: (Nothing) => MyList[B]): MyList[B] = ???
override def map[B](f: (Nothing) => B): MyList[B] = ???
}
case class MyCons[A](head: A, tail: MyList[A]) extends MyList[A] {
override def flatMap[B](f: (A) => MyList[B]): MyList[B] = ???
override def map[B](f: (A) => B): MyList[B] = ???
}
我的测试是:
import org.scalacheck.{Gen, Arbitrary}
import org.scalatest.{ShouldMatchers, FunSuite}
import org.scalatest.prop.Checkers
import org.scalacheck.Prop.forAll
class MyListSpec extends FunSuite with ShouldMatchers with Checkers {
private def myConsGen[T]: Gen[MyList[T]] = for {
head <- Arbitrary.arbitrary[T]
tail <- Gen.oneOf(myNilGen, myConsGen[T])
} yield MyCons(head, tail)
private val myNilGen: Gen[MyList[Nothing]] = Gen.wrap(MyNil)
implicit def myListArbitrary[T]: Arbitrary[MyList[T]] = Arbitrary[MyList[T]](Gen.oneOf(myNilGen, myConsGen[T]))
test("map") {
check(forAll { l: MyList[String] =>
l.map(s => s) == l
})
}
}
但是我编译的时候会报错:
Error:(12, 32) could not find implicit value for parameter a: org.scalacheck.Arbitrary[T]
head <- Arbitrary.arbitrary[T]
^
Error:(12, 32) not enough arguments for method arbitrary: (implicit a: org.scalacheck.Arbitrary[T])org.scalacheck.Gen[T].
Unspecified value parameter a.
head <- Arbitrary.arbitrary[T]
^
如何解决?我的方法是否可以改进?
您需要证明 T
有一个 Arbitrary
实例。
def myConsGen[T:Arbitrary]: Gen[MyList[T]]
和
implicit def myListArbitrary[T:Arbitrary]
我定义了一个自定义列表并想用 scalacheck 测试它:
sealed trait MyList[+A] {
def flatMap[B](f: A => MyList[B]): MyList[B]
def map[B](f: A => B): MyList[B]
}
case object MyNil extends MyList[Nothing] {
override def flatMap[B](f: (Nothing) => MyList[B]): MyList[B] = ???
override def map[B](f: (Nothing) => B): MyList[B] = ???
}
case class MyCons[A](head: A, tail: MyList[A]) extends MyList[A] {
override def flatMap[B](f: (A) => MyList[B]): MyList[B] = ???
override def map[B](f: (A) => B): MyList[B] = ???
}
我的测试是:
import org.scalacheck.{Gen, Arbitrary}
import org.scalatest.{ShouldMatchers, FunSuite}
import org.scalatest.prop.Checkers
import org.scalacheck.Prop.forAll
class MyListSpec extends FunSuite with ShouldMatchers with Checkers {
private def myConsGen[T]: Gen[MyList[T]] = for {
head <- Arbitrary.arbitrary[T]
tail <- Gen.oneOf(myNilGen, myConsGen[T])
} yield MyCons(head, tail)
private val myNilGen: Gen[MyList[Nothing]] = Gen.wrap(MyNil)
implicit def myListArbitrary[T]: Arbitrary[MyList[T]] = Arbitrary[MyList[T]](Gen.oneOf(myNilGen, myConsGen[T]))
test("map") {
check(forAll { l: MyList[String] =>
l.map(s => s) == l
})
}
}
但是我编译的时候会报错:
Error:(12, 32) could not find implicit value for parameter a: org.scalacheck.Arbitrary[T]
head <- Arbitrary.arbitrary[T]
^
Error:(12, 32) not enough arguments for method arbitrary: (implicit a: org.scalacheck.Arbitrary[T])org.scalacheck.Gen[T].
Unspecified value parameter a.
head <- Arbitrary.arbitrary[T]
^
如何解决?我的方法是否可以改进?
您需要证明 T
有一个 Arbitrary
实例。
def myConsGen[T:Arbitrary]: Gen[MyList[T]]
和
implicit def myListArbitrary[T:Arbitrary]