我定义了一个自定义列表,并希望使用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]
^
如何解决?我的方法能够得到改善吗?
答案 0 :(得分:3)
您需要提供T
具有Arbitrary
实例的证据。
def myConsGen[T:Arbitrary]: Gen[MyList[T]]
和
implicit def myListArbitrary[T:Arbitrary]