Да, точно так же, как вы генерировали бы произвольные значения других типов:
import org.scalacheck._
// Int instead of Boolean to better see that it is a function
val arb = implicitly[Arbitrary[String => Int]].arbitrary.sample.get
println(arb("a"))
println(arb("a")) // same
println(arb("b"))
, потому что существуют неявные Cogen[String]
и Arbitrary[Boolean]
. Cogen
не задокументировано в руководстве пользователя, но оно эквивалентно CoArbitrary
QuickCheck, которое объясняется в https://kseo.github.io/posts/2016-12-14-how-quick-check-generate-random-functions.html и https://begriffs.com/posts/2017-01-14-design-use-quickcheck.html (в разделе «CoArbitrary and Gen (a -> b) ").
Можно ли тогда генерировать произвольную функцию из класса случайных случаев? Например,
case class File(name: Str, size:Long)
Этого должно быть достаточно для определения Cogen[File]
. Либо вручную:
implicit val cogenFile: Cogen[File] = Cogen {
(seed: Seed, file: File) => Cogen.perturbPair(seed, (file.name, file.size))
}
Чуть больше кода, но обобщается более чем в 2 поля:
implicit val cogenFile: Cogen[File] = Cogen { (seed: Seed, file: File) =>
val seed1 = Cogen.perturb(seed, file.name)
Cogen.perturb(seed1, file.size)
}
Или автоматически используется scalacheck-shapeless :
implicit val cogenFile: Cogen[File] = MkCogen[File].cogen