2014-02-08 2 views
0

ScalaCheck 도구를 배우려고 할 때 Map Generator의 두 가지 버전을 작성했습니다 (이 중 하나가 내장되어 있음을 알고 있지만 이것은 운동이었습니다).왜 이러한 scalacheck 재귀 생성기가 동일하지 않습니까?

genMap0genMap00이 동일해야한다는 것, 그리고 genMap00genMap0 작품을 비트 청소기이지만, 사실,하지만 genMap00 비참하게 실패합니다.

yield은 (단지 speak 방법을 편집) 일어나는 것을 볼 수 켤 수있는 println로 장식되어 있지만, 심지어는이 정보를 내가 정말 왜 차이를 이해 말할 수 없습니다. 이것은 내가 쓰려고하는 또 다른 발전기가 결함이 있다고 생각하게 만든다.

누군가 genMap0genMap00 사이에 다른 점에 대해 설명 할 수 있습니까?

import org.scalacheck._ 
    import Arbitrary._ 
    import Gen._ 
    import Prop._ 

    def speak(message: String): Unit = if (false) println(message) 

    lazy val genMap0: Gen[Map[Int, Int]] = for { 
    k <- arbitrary[Int] 
    v <- arbitrary[Int] 
    b <- arbitrary[Boolean] 
    m <- if (b) value(Map.empty[Int, Int]) else genMap0 
    } yield if (b) { 
    speak("false"); m 
    } else { 
    speak("true"); m.updated(k, v) 
    } 

    lazy val genMap00: Gen[Map[Int, Int]] = for { 
    k <- arbitrary[Int] 
    v <- arbitrary[Int] 
    m <- oneOf(Map.empty[Int, Int], genMap00) 
    } yield if (m.isEmpty) { 
    speak("empty:" + m); m 
    } else { 
    speak("not empty:" + m); m.updated(k, v) 
    } 

    val n = 5 
    for (i <- 1 to n; m <- genMap0.sample) println(m) 
    println("--------------") 
    for (i <- 1 to n; m <- genMap00.sample) println(m) 

은 ( genMap00 항상 빈 상태 (empty)의 맵을 생성)의 출력입니다 :

scala -cp scalacheck_2.10-1.10.1.jar 
... 
// Exiting paste mode, now interpreting. 

Map() 
Map(1 -> 1, 1530546613 -> -1889740266, -187647534 -> 0) 
Map() 
Map(-1 -> 2039603804) 
Map(646468221 -> 1) 
-------------- 
Map() 
Map() 
Map() 
Map() 
Map() 

답변

1

재귀 세대는 항상 빈지도로 시작 문제는, 그래서 gen00 항상을 생산하는 발전기로 끝납니다 빈지도. 문제는 빈 상태가 종료 감지에도 사용된다는 것입니다.

gen000은이 고정되어있다 :이 None 상태를 나타내는 종단과 중간 Option[Map] 사용

lazy val genMap000: Gen[Map[Int, Int]] = for { 
    k <- arbitrary[Int] 
    v <- arbitrary[Int] 
    m <- oneOf(None, genMap000.map(g => Some(g))) 
    } yield (for (x <- m) yield x.updated(k, v)).getOrElse(Map()) 

.

명시적인 Boolean 생성기를 사용하면 더 깨끗해 보입니다.

관련 문제