2016-09-26 20 views
0

我對ScalaCheck有以下代碼。這個想法是使用Java HashSet作爲容器自動生成整數集合。以下代碼用於幾年前的工作,但不再編譯。Scalacheck新的可構建實例

import java.util.HashSet 

import scala.collection._ 

import org.scalacheck.Properties 
import org.scalacheck.Prop._ 
import org.scalacheck.util.Buildable 

package simpletest { 

    class SimpleSpecification extends Properties("Simple") { 

     implicit def buildableHashSet[T] : Buildable[T,HashSet[T]] = new Buildable[T, HashSet[T]] { 
      def builder = new mutable.Builder[T,HashSet[T]] { 
       val al = new HashSet[T] 
       def +=(x: T) = { 
        al.add(x) 
        this 
       } 
       def clear() = al.clear() 
       def result() = al 
      } 
     } 

     property("simple") = 
      forAll{(a: HashSet[Int]) => 
       a.size() == 1 
      } 

    } 
} 

現在失敗

...simpletest/SimpleSpecification.scala:26: could not find implicit value for parameter a1: org.scalacheck.Arbitrary[java.util.HashSet[Int]]    
forAll{(a: HashSet[Int]) => 

我已經廣泛搜索使用可建造的指令,但只能找到scalacheck用戶指南中的一個過客參考。據我所知,我的用法與Buildable.scala中的用法相匹配(由用戶指南指出)。有沒有人有任何想法在過去幾年發生了什麼變化,以及如何更新我的代碼以使其再次運行?

回答

0

forAll()要求暗示Arbitrary[HashSet[Int]]。它可以使用Gen.containerOf()與隱含的Buildable[T,HashSet[T]]HashSet[T] => Traversable[T]來定義。

的代碼是這樣:

package simpletest 

import java.util.HashSet 

import org.scalacheck.Arbitrary.arbitrary 
import org.scalacheck.Prop._ 
import org.scalacheck.util.Buildable 
import org.scalacheck.{Arbitrary, Gen, Properties} 

import scala.collection.JavaConverters._ 
import scala.collection._ 
import scala.language.implicitConversions 


class SimpleSpecification extends Properties("Simple") { 

    implicit def buildableHashSet[T]: Buildable[T, HashSet[T]] = new Buildable[T, HashSet[T]] { 
    def builder = new mutable.Builder[T, HashSet[T]] { 
     val al = new HashSet[T] 

     def +=(x: T) = { 
     al.add(x) 
     this 
     } 

     def clear() = al.clear() 

     def result() = al 
    } 
    } 

    implicit def hashSetTraversable[T](hashSet: HashSet[T]): Traversable[T] = { 
    hashSet.asScala 
    } 

    implicit val intHashSetGen: Arbitrary[HashSet[Int]] = 
    Arbitrary(Gen.containerOf[HashSet, Int](arbitrary[Int])) 

    property("simple") = 
    forAll { (a: HashSet[Int]) => 
     a.size() == 1 
    } 

} 
+0

謝謝你。事實上,解決方案可以變得更簡單:intHashSetGen的定義不是必需的,隱式轉換爲可遍歷就足夠了。我也意識到我應該將SimpleSpecification作爲一個對象來聲明。我在下面的答案中包含了我的最終解決方案。 –

0

這是我的最終解決方案。按照Kawty的建議,我從HashSet [T]向Traversable [T]添加了一個隱式函數(但不需要intHashSetGen)。我還將SimpleSpecification作爲一個對象,並使該屬性更有趣一些。

import java.util.HashSet 

import scala.collection._ 
import scala.collection.JavaConverters._ 

import org.scalacheck.Properties 
import org.scalacheck.Prop._ 

import org.scalacheck.util.Buildable 

package simpletest { 

    object SimpleSpecification extends Properties("Simple") { 

     implicit def buildableHashSet[T] : Buildable[T,HashSet[T]] = new Buildable[T,HashSet[T]] { 
      def builder = new mutable.Builder[T,HashSet[T]] { 
       val al = new HashSet[T] 
       def +=(x: T) = { 
        al.add(x) 
        this 
       } 
       def clear() = al.clear() 
       def result() = al 
      } 
     } 

     implicit def traverseHashSet[T](s : HashSet[T]) : Traversable[T] = s.asScala 

     property("simple") = 
      forAll{(a: HashSet[Int]) => 
       a.size() < 2 
      } 
    } 
}