2017-12-11 7 views
2

モナドタイプのクラスを定義しました。私はscalacheckでその法則を検証しようとしています。より大きい種類の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) 
    } 
    } 
} 

は私が暗黙の任意の種類でsoemthingを逃しましたか?ここで

は私のモナドです:

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) 
    } 
} 

おかげ

答えて

2

あなたがスコープで暗黙のArbitrary[Box[A]]を持っていますが、あなたは(ScalacheckがA => Box[B]のための1つを作成する必要がある)Arbitrary[Box[B]]のための1つを持っているかのためにはありませんArbitrary[Box[C]](これは後で尋ねます)。

より理にかなったアプローチが

trait Arbitrary1[F[_]] { 
    def liftArb[A](arb: Arbitrary[A]): Arbitrary[F[A]] 
} 

のようなものを作成し、Arbitrary1[Box]を提供するだろうが、それはforAllを呼び出すときに、より明示的であることが必要となります。

+0

ありがとうございました:) – Loic

関連する問題