如何在scalacheck中为自定义列表定义任意值?

时间:2015-08-07 13:27:15

标签: scala 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]
                               ^

如何解决?我的方法能够得到改善吗?

1 个答案:

答案 0 :(得分:3)

您需要提供T具有Arbitrary实例的证据。

def myConsGen[T:Arbitrary]: Gen[MyList[T]]

implicit def myListArbitrary[T:Arbitrary]