更高种类的 Scalacheck 问题:Arbitrary 类型的发散隐式扩展
Scalacheck issue with higher kinds : diverging implicit expansion for type Arbitrary
我已经定义了一个 monad 类型 class,我正在尝试用 scalacheck 验证它的规律。
我有以下错误:
diverging implicit expansion for type org.scalacheck.Arbitrary[(A, Box[B])]
我的 scalacheck 代码如下:
class OptionMonadSpec extends MonadSpec[String, String, String, Option](Monad.optionMonad)
abstract class MonadSpec[A, B, C, Box[_] : ClassTag](monad: Monad[Box])
(implicit boxArb: Arbitrary[Box[A]], aArb: Arbitrary[A], bArb: Arbitrary[B], cArb: Arbitrary[C])
extends Properties(s"Monad for ${classTag[Box[_]]}") {
property("left identity") = forAll { (f: (A => Box[B]), a: A) =>
val boxA: Box[A] = monad.pure(a)
monad.flatMap(boxA)(f) == f(a)
}
property("right identity") = forAll { box: Box[A] =>
monad.flatMap(box)(monad.pure) == monad
}
property("associativity") = forAll { (f: (A => Box[B]), g: (B => Box[C]), box: Box[A]) =>
val boxB: Box[B] = monad.flatMap(box)(f)
monad.flatMap(boxB)(g) == monad.flatMap(box) { a =>
val boxB: Box[B] = f(a)
monad.flatMap(boxB)(g)
}
}
}
我是否遗漏了隐式任意类型中的某些内容?
这是我的单子:
trait Monad[Box[_]] extends Functor[Box] {
def pure[A](a: A): Box[A]
def flatMap[A, B](boxA: Box[A])(f: A => Box[B]): Box[B]
}
object Monad {
implicit val optionMonad = new Monad[Option] {
override def pure[A](x: A): Option[A] = Some(x)
override def flatMap[A, B](boxA: Option[A])(f: A => Option[B]) = boxA.flatMap(f)
override def map[A, B](boxA: Option[A])(f: A => B) = boxA.map(f)
}
}
谢谢
您在范围内有一个隐式 Arbitrary[Box[A]]
,但您没有 Arbitrary[Box[B]]
(Scalacheck 需要为 A => Box[B]
创建一个)或 Arbitrary[Box[C]]
(之后它会要求)。
一个更有原则的方法是创建类似
的东西
trait Arbitrary1[F[_]] {
def liftArb[A](arb: Arbitrary[A]): Arbitrary[F[A]]
}
并提供 Arbitrary1[Box]
但在调用 forAll
.
时需要更明确
我已经定义了一个 monad 类型 class,我正在尝试用 scalacheck 验证它的规律。
我有以下错误:
diverging implicit expansion for type org.scalacheck.Arbitrary[(A, Box[B])]
我的 scalacheck 代码如下:
class OptionMonadSpec extends MonadSpec[String, String, String, Option](Monad.optionMonad)
abstract class MonadSpec[A, B, C, Box[_] : ClassTag](monad: Monad[Box])
(implicit boxArb: Arbitrary[Box[A]], aArb: Arbitrary[A], bArb: Arbitrary[B], cArb: Arbitrary[C])
extends Properties(s"Monad for ${classTag[Box[_]]}") {
property("left identity") = forAll { (f: (A => Box[B]), a: A) =>
val boxA: Box[A] = monad.pure(a)
monad.flatMap(boxA)(f) == f(a)
}
property("right identity") = forAll { box: Box[A] =>
monad.flatMap(box)(monad.pure) == monad
}
property("associativity") = forAll { (f: (A => Box[B]), g: (B => Box[C]), box: Box[A]) =>
val boxB: Box[B] = monad.flatMap(box)(f)
monad.flatMap(boxB)(g) == monad.flatMap(box) { a =>
val boxB: Box[B] = f(a)
monad.flatMap(boxB)(g)
}
}
}
我是否遗漏了隐式任意类型中的某些内容?
这是我的单子:
trait Monad[Box[_]] extends Functor[Box] {
def pure[A](a: A): Box[A]
def flatMap[A, B](boxA: Box[A])(f: A => Box[B]): Box[B]
}
object Monad {
implicit val optionMonad = new Monad[Option] {
override def pure[A](x: A): Option[A] = Some(x)
override def flatMap[A, B](boxA: Option[A])(f: A => Option[B]) = boxA.flatMap(f)
override def map[A, B](boxA: Option[A])(f: A => B) = boxA.map(f)
}
}
谢谢
您在范围内有一个隐式 Arbitrary[Box[A]]
,但您没有 Arbitrary[Box[B]]
(Scalacheck 需要为 A => Box[B]
创建一个)或 Arbitrary[Box[C]]
(之后它会要求)。
一个更有原则的方法是创建类似
的东西trait Arbitrary1[F[_]] {
def liftArb[A](arb: Arbitrary[A]): Arbitrary[F[A]]
}
并提供 Arbitrary1[Box]
但在调用 forAll
.