2016-09-26 3 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]]이 필요합니다. 암시적인 Buildable[T,HashSet[T]]HashSet[T] => Traversable[T]이있는 Gen.containerOf()을 사용하여 정의 할 수 있습니다.

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