ããŒã2.ãžã§ãã¬ãŒã¿ãŒ
ãã®ã·ãªãŒãºã®å
¥éèšäºã§ããžã§ãã¬ãŒã¿ãŒãæ¢ã«ç¥ã£ãŠããããšãé¡ã£ãŠããŸãã ãã®ãã¥ãŒããªã¢ã«ã§ã¯ãåŠç¿ããç¥èãçµ±åããç¬èªã®ïŒååž°ãå«ãïŒãžã§ãã¬ãŒã¿ãŒã®äœææ¹æ³ãåŠç¿ããŸãã ãžã§ãã¬ãŒã¿ãŒå°çšã§ãããããããã£ã«ã€ããŠãå¿ããŸããã ããã«ãããããç©æ¥µçã«äœ¿çšããŠããžã§ãã¬ãŒã¿ãŒã¡ã«ããºã ã®ãã«ãã¯ãŒãå®èšŒããŸãã åææ¡ä»¶ã®ã¡ã«ããºã ãæ€èšããŠãã ããã ãããããã·ãªãŒãºã®2çªç®ã®èšäºãããããã£ã«åœãŠãæ¹ãè«ççã§ããããããããããæ£ããæ±ºå®ã§ãããã ããããç§ã®å人çãªèгå¯ã«ãããšãæãå°é£ãªã®ã¯ãžã§ãã¬ãŒã¿ãŒã§ãã æ¬¡ã®èšäºã§ããããã£ãæ€èšããŸãã
ãµã€ã¯ã«æ§é 
çºé»æ©
Propãªããžã§ã¯ãã®forAllã¡ãœããã¯ãã©ã³ãã ã«çæãããããŒã¿ã䜿çšããŸãã åçŽãªããŒã¿åãŸãã¯ã³ã³ããïŒ è€å ïŒåã®ããããã§ãã ScalaCheckã§ã¯ããžã§ãã¬ãŒã¿ãŒã¯Genã®åå«ã§ãã
 sealed abstract class Gen[+T] { def apply(prms: Gen.Params): Option[T] ... } 
ã¯ã©ã¹ã¯ãçæãããå€ã®ã¿ã€ãã«ãã£ãŠãã©ã¡ãŒã¿ãŒã決ãŸããŸãã ãããã£ãŠãæååã«ã¯Gen[String]ããããæªåé«ãPerson - Gen[Person]ãŸãã å¿
èŠãªåœ±é¿ãç¯å²å
ã§ããã°ã Arbitraryãªããžã§ã¯ãã®arbitraryã¡ãœããã䜿çšããããšãã§ããŸãã
ãžã§ãã¬ãŒã¿ãŒã«æé»çãªãµããŒãã远å ããŸã
æé»ã®ããšã話ããŠããã®ã§ã arbitrary
ããªãã®ã¿ã€ãã«ã ãŸããåèªäœãå¿
èŠã§ãã
 sealed trait LED case object Red extends LED case object Green extends LED case object Blue extends LED 
次ã«ããã€ãªãŒãçšã®ãžã§ãã¬ãŒã¿ãŒãäœæããŸãã
 val ledGenerator: Gen[LED] = Gen.oneOf(Red, Green, Blue) 
ããã§ããžã§ãã¬ãŒã¿ãŒããimplicit Arbitraryã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã
 implicit val arbitraryLed: Arbitrary[LED] = Arbitrary(ledGenerator) Arbitrary.arbitrary[LED].sample  
ããã§ãã¹ã³ãŒãå
ã«LEDãããã®ã§ãããã€ãã®ããããã£ã確èªã§ããŸãã
 val ledProp = forAll { diode: LED =>  
倿°ã®ããªããã£ãåãšæšæºã©ã€ãã©ãªã®ã³ã³ããã®å Žåãæé»çãªå€æã¯Arbitraryãªããžã§ã¯ãå
ã§ãã§ã«äºåå®çŸ©ãããŠããŸãã
 import org.scalacheck.Arbitrary.arbitrary val arbitraryString = arbitrary[String] val arbitraryInteger = arbitrary[Int] 
Gen.resultOfã¯ããã®åé¡ã§ããªãã倧ãã«å©ããããšãã§ããŸãã ãã®é¢æ°ã¯ã arbitraryå€ãæ¢ã«å®çŸ©ãããŠããã³ã³ã¹ãã©ã¯ã¿ãŒãã©ã¡ãŒã¿ãŒã«å¯ŸããŠãã±ãŒã¹ã¯ã©ã¹ãåãå
¥ããŸãã
 case class Coord(x: Double, y: Double)  
sampleæ¹æ³
æ®å¿µãªããã toStringã¡ãœããã¯Genã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã«å¯ŸããŠå®çŸ©ãããŠããŸãããããã䟿å©ã§äŸ¿å©ãªã¡ãœããããããŸãã ãžã§ãã¬ãŒã¿ãŒãäœæãããšãã«ã¯ãéåžžã«é »ç¹ã«äœ¿çšããå¿
èŠãããããŸãã ããã¯Gen.sampleã¡ãœããã§ãã Optionå
ã§çæãããå€ã®äŸãè¿ããŸãã
 // ScalaCheck     ,   //  10 . Arbitrary.arbitrary[String].sample map (_ take 10) //     . // Some(ïŒ±åæ§éŸî¬èœâ®»æç®ã) Arbitrary.arbitrary[Double].sample // Some(-5.180668081211655E245) 
åã®ããŒãã§ãã§ã«èª¬æããããã«ã mapã¡ãœããã¯ãžã§ãã¬ãŒã¿ãŒã«ãé©çšã§ããŸãã ãããæ¬¡ã®äŸã§èª¬æããŸãã
 val octDigitStr = choose(0, 7) map (_.toString) octDigitStr.sample  
ãã£ã«ã¿ãªã³ã°
ãžã§ãã¬ãŒã¿ãŒçšã®filterã¡ãœããããããŸãããå®éã«ã¯ãããã¯suchThatã¡ãœãããåŒã³åºãããã®åãªããšã€ãªã¢ã¹ã§ãã
 val evenOct = octDigit.filter(_ % 2 == 0) evenOct.sample // None //  ,   : evenOct.sample // None //  ,    ? evenOct.sample // Some(2) 
äžèšã®äŸã¯ã filterãsuchThat䜿çšããªãçç±ã瀺ããŠããŸãã æ°ãããžã§ãã¬ãŒã¿ãŒã¯ããã£ã«ã¿ãŒãééããªãå€ãåã«æåŠããŸãã ããã«ããããã¹ãããã»ã¹ã倧å¹
ã«é
ããªããŸãã
åææ¡ä»¶ã¯ãã£ã«ã¿ãŒãšåæ§ã«æ©èœããŸãã
åææ¡ä»¶
ScalaCheckã®å«ææäœã«ãã£ãŠããžãã¯ã§æç€ºãããåææ¡ä»¶ã¯ãããããã£å
ã§äœ¿çšãããã¡ãœããã§ãã å
¥åãå¶éããããšãã§ããŸãã æŒç®å==>ã«ãã£ãŠæžãããŸããã åææ¡ä»¶ã䜿çšããã«ã¯ã Prop.propBooleanã«è¿œå ããå¿
èŠãããProp.propBoolean ã ãããã£ãŠãå¶æ°ã®å ŽåãæåŸã®æ¡ãå¶æ°ã«ãªããšããã¹ããŒãã¡ã³ãã確èªããŸãããã
 import org.scalacheck.Prop.{forAll, propBoolean} def isEven(number: Int) = number % 2 == 0 //    . def lastChar(number: Int) = number.toString.last.toInt // . val p2 = forAll(arbitrary[Int] suchThat isEven) { number => isEven(lastChar(number)) } //  . val p1 = forAll(arbitrary[Int]) { number => isEven(number) ==> isEven(lastChar(number)) } 
ããããã£ãéå§ããã«ã¯ã checkæ©èœã䜿çšã§ããŸãã
 //     p1.check // + OK, passed 100 tests. //   p2.check // + OK, passed 100 tests. 
ãã£ã«ã¿ãŒã硬ãã»ã©ãããå€ãã®å€ãç¡èŠãããŸãã ããã¯ãå€ã®å°ããªã»ãããŸãã¯äºãã«éåžžã«é¢ããŠããå€ã®å Žåã«éèŠã«ãªãããšããããŸãã ããšãã°ãç¯å²Intã®çŽ æ°ã ãã®ãããªåãçµã¿ãããScalaCheckã¯ç°¡åã«ç²ããŠãããªãã«éäŒããããšãã§ããŸãã
 scala> p1.check ! Gave up after only 1 passed tests. 100 tests were discarded 
å¶æ°ã®äŸã§ã¯ããã«æ°ä»ããªãã§ãããããåçŽãªæ°ã®äŸã§ã¯ç°¡åã§ãã æ¬¡ã®ããšãç¥ã£ãŠããå¿
èŠããããŸãã
å¶æ°ã®ãã£ã«ã¿ãŒã¯ããŸããŸãªæ¹æ³ã§å®è£
ã§ããŸãã ããšãã°ãããªãã¯åãããšãã§ããŸã
ä»»æã®æŽæ°ã§ã2ãæããŸãã玠æ°ã®å Žå
äºåã«ã«ãŠã³ãããæ¹ãã¯ããã«ç°¡åã§ããããšãã°ã
ãšã©ãã¹ããã¹ã®ãµãã ããããŠãªã¹ããçªãåºã
Gen.oneOfå
ã®èšç®å€ãããã«ã€ããŠã¯åŸã§èª¬æããŸã
èšäºã
suchThatã䜿çšããŠãžã§ãã¬ãŒã¿ãŒãsuchThat ãåé¡ãçºçããå¯èœæ§ããããŸãã ãã®ãããªå Žåã¯ã retryUtilã¡ãœããã䜿çšããå¿
èŠããããŸãã suchThatãšã¯ç°ãªããScalaCheckã®åäœãé£ãããªããç¡éã«ãŒãã«é¥ãããšããããŸãã retrtyUtilãretrtyUtil fiterãŸãã¯suchThat䌌ãŠãsuchThat ïŒ
 arbitrary[Int] retryUntil isEven 
ãŸãã fromOption flattenãšflatten ãããã³fromOptionãDeprecatedãšå®£èšãããŠããããšã«fromOptionãããããŸããã ããã¯ã空ã®ãžã§ãã¬ãŒã¿ãŒãäœæããèªæãå°ãªãããããã«è¡ãããŸãã
ç¬èªã®ãžã§ãã¬ãŒã¿ãŒãäœæãã
åè¿°ã®ããã«ãæ¢åã®ãžã§ãã¬ãŒã¿ãŒãçè§£ã®ããã«çµã¿åãããããšã§ãç¬èªã®ãžã§ãã¬ãŒã¿ãŒãäœæã§ããŸãã
 val coordGen = for { i <- arbitrary[Int]; j <- arbitrary[Int] } yield (i, j) coordGen.sample // Option[(Int, Int)] = Some((45,60)) coordGen.sample // Option[(Int, Int)] = Some((29, 37)) 
ä»»æã®ããŒã¿æ§é ã®ãžã§ãã¬ãŒã¿ãŒã宣èšã§ããŸãã ADTã䜿çšããåçŽãªã±ãŒã¹ïŒ
 sealed trait LightColor case object Red extends LightColor case object Orange extends LightColor case object Green extends LightColor case object FlashingGreen extends LightColor case object Extinct extends LightColor val colorGen = Gen.oneOf(Red, Orange, Green, Extinct) 
人çãè€éã«ããŠãããªãã培åºçã«ïŒ
 //       ,     . type Color = LightColor object PedestrianTrafficLight { sealed class State(_1: Color, _2: Color) case object Stop extends State(Red, Extinct) case object Move extends State(Extinct, Green) case object FinishMove extends State(Extinct, FlashingGreen) def states: Seq[State] = Seq(Move, FinishMove, Stop) } object VehicularTrafficLight { sealed class State(_1: Color, _2: Color, _3: Color) case object Stop extends State(Red, Extinct, Extinct) case object Ready extends State(Red, Orange, Extinct) case object Move extends State(Extinct, Extinct, Green) case object Warn extends State(Red, Orange, Extinct) case object FinishMove extends State(Extinct, Extinct, FlashingGreen) def states: Seq[State] = Seq(Stop, Ready, Move, Warn, FinishMove) } sealed trait TrafficLight case class PedestrianTrafficLight(state: PedestrianTrafficLight.State) extends TrafficLight case class VehicularTrafficLight(state: VehicularTrafficLight.State) extends TrafficLight 
ãžã§ãã¬ãŒã¿ãŒã宣èšããŸãã
 import Gen._ //      val pedestrianTrafficLightStateGen = Gen.oneOf(PedestrianTrafficLight.states) //      val vehicularTrafficLightStateGen = Gen.oneOf(VehicularTrafficLight.states) 
ãããŠãæ©è¡è
ãšäº€éä¿¡å·ããã¿ãã«ãçæããŸãã äžã€ã ããããŸãïŒä¿¡å·æ©ã®ç¶æ
ã¯çžäºã«æä»çã§ãã£ãŠã¯ãªããŸããã ãŸããæ©è¡è
ãæäœã§ããæ¡ä»¶ãæ±ºå®ããŸãã åæã«ãã£ãŠãžã§ãã¬ãŒã¿ãŒãäœæããããã retryUntil代ããã«suchThatã䜿çšããŸãã
 val pedestrianCanGo = pedestrianTrafficLightStateGen.retryUntil { state => state != PedestrianTrafficLight.Stop } 
次ã«ãä¿¡å·æ©ã®ç¶æ
ãçæããããããå§ããŠãæ©è¡è
ã®èš±å®¹ç¶æ
ãæ±ºå®ãããããããªã¹ãã«çµåããŸãã åãåã£ããžã§ãã¬ãŒã¿ãŒã®ã¿ã€ãã¯ã Gen[(VehicularTrafficLight.State, PedestrianTrafficLight.State)]ã§ãã
 val states = vehicularTrafficLightStateGen flatMap { case vehState @ VehicularTrafficLight.Stop => pedestrianCanGo map (pedState => (vehState, pedState)) case pedestrianCanNotGo => (pedestrianCanNotGo, PedestrianTrafficLight.Stop) } 
ãªããžã§ã¯ãèªäœã«ä¿¡å·æ©ã®ã¹ããŒã¿ã¹ã衚瀺ããŸãïŒ
 val trafficLightPair = states map { case (v, p) => (VehicularTrafficLight(v), PedestrianTrafficLight(p)) } 
çµæã確èªããŸããïŒ ç§ã¯åãåã£ãïŒ
 (VehicularTrafficLight(FinishMove),PedestrianTrafficLight(Stop)) 
ãããŠ
 (VehicularTrafficLight(Move),PedestrianTrafficLight(Stop)) 
ããã¯å
šãæ¬åœã§ãã å€åã©ããç§ãééã£ãŠããã äž»ãªããšã¯ãã¡ã«ããºã èªäœãå®èšŒããããšã§ããã
ScalaCheckã§ã¯ãååž°çãªããŒã¿æ§é ãçæããããšãã§ããŸãã
ãã ãããã®ããã»ã¹ãç°¡åãã€äºçްãªããšãšåŒã¶ããšã¯å°é£ã§ãã ããã«ããã§
ãã®èšäºã§ã¯ãååž°ãžã§ãã¬ãŒã¿ãŒãšããã®åé¡ã«ã€ããŠèŠãŠãããŸãã
ãããã䜿çšãããšãã«ééãããããããŸããã
ããããã£ã®ãžã§ãã¬ãŒã¿ãŒ
åè¿°ã®ã»ãšãã©ã®äŸã§ã¯ãScalaCheckã¯ãžã§ãã¬ãŒã¿ãŒã®é©åãªã€ã³ã¹ã¿ã³ã¹ãåå¥ã«éžæããããã䜿çšããŠããããã£ãèšç®ããŸãã ãã ãããžã§ãã¬ãŒã¿ãŒãç¬èªã«äœæããã®ã¯ãã®ããã§ã¯ãªããScalaCheckã¯ã¹ã³ãŒãããäœããåé€ããŸãã ãäºææ§ã®ãããä¿¡å·æ©ãèŠããŠããŸããïŒ ããããã©ããã«ããã·ã¥ããŸãããïŒ
 import Prop.{forAll, propBoolean} def isRed(trafficLight: VehicularTrafficLight) = trafficLight.state == VehicularTrafficLight.Stop def notRed(trafficLight: PedestrianTrafficLight) = trafficLight.state != PedestrianTrafficLight.Stop //        Prop.forAll val canNotBothBeRed = forAll(trafficLightPair) { case (vehicular, pedestrian) => isRed(vehicular) ==> notRed(pedestrian) } 
ãã§ãã¯ããŠã¿ãŠïŒ
 canNotBothBeRed.check 
ãããŠããã¹ãŠãæ£åžžã§ããããšã確èªããŸãã
 + OK, passed 100 tests. 
å€ãã®å Žåã1ã€ã®ãžã§ãã¬ãŒã¿ãŒã§ã¯ååã§ã¯ãªããããè€æ°ã®ãžã§ãã¬ãŒã¿ãŒã䜿çšã§ããŸãã
 val p = forAll(Gen.posNum[Int], Gen.negNum[Int]) { (pos, neg) => neg < pos } 
ãžã§ãã¬ãŒã¿ãŒãªã©ã®ããããã£ã¯ãäžç·ã«ãã¹ãã§ãããããäžèšã®äŸã次ã®ããã«æžãæããããšãã§ããŸãã
 val p = forAll(Gen.posNum[Int]) { pos => forAll(Gen.negNum[Int]) { neg => neg < pos } } 
ãã¹ããããforAllåŒã³åºãã®ä»£ããã«ã䜿çšãããžã§ãã¬ãŒã¿ãŒããã¿ãã«ãã³ã³ãã€ã«ããããšãã§ããŸãã ãŸãã forAll 2ååŒã³åºããªãã§ãã ããã
çºé»æ©ã®ã©ãã«
ã¿ã°ã䜿çšããããšããå§ãããŸãã ããã«ããããšã©ãŒå ±åãæ¹åããããžã§ãã¬ãŒã¿ãŒã䜿çšããã³ãŒãã®å¯èªæ§ãåäžããŸãã ã©ãã«ã远å ããã«ã¯ã |:ããã³:|䜿çšã§ããŸã:| ã ã©ãã«ã¯ãæååãŸãã¯æåã®ããããã§ãã è€æ°ã®ã¿ã°ããžã§ãã¬ãŒã¿ã«è¿œå ã§ããŸãã 説æããããã«ãåã®äŸã䜿çšããŠã èšå·ã倿Žããããããã£ãäžæ¡çã«ããŸãã
 //  |:  :|   . val p = forAll('positive |: Gen.posNum[Int]) { pos => forAll(Gen.negNum[Int] :| "negative numbers") { neg => neg > pos } } 
åæããŠãè¯ããªã£ãïŒ
 ! Falsified after 0 passed tests. > positive: 0 > positive_ORIGINAL: 1 > negative numbers: 0 
ããªããã£ããžã§ãã¬ãŒã¿ãŒ
宿°
Gen.constãããç°¡åãªãã®ãGen.constã¯Gen.constã§ãã ä»»æã®å€ãåãããžã§ãã¬ãŒã¿ãŒã«æ³šææ·±ãããã¯ããŸãã é©åãªã¿ã€ãã³ã°ã§é©åãªå Žæã«ãããªããžã§ã¯ãã¯ãæé»çã«Genãã£ã¹ããããŸãGen ãããã£ãŠãã»ãšãã©ã®å Žåããã®ã¡ãœãããæç€ºçã«åŒã³åºãå¿
èŠã¯ãããŸããã
æ»ã¬
ScalaCheckã¯ãå®è¡äžå¯èœãªãžã§ãã¬ãŒã¿ãŒãè¿ãGen.failã¡ãœããã䜿çšããŸãã sampleã¡ãœãããåŒã³åºãããšãããšãåžžã«NoneãŸãã ã»ãšãã©ã®å Žåã圌ã¯ããªãã®æ¹æ³ã§äŒãããšã¯ãããŸããã圌ãäŒã£ãå Žåãããªãã¯åœŒã«ç²ŸéããŠããããšãèæ
®ããŠãã ããïŒ
 Gen.fail.sample // Option[Nothing] = None 
æ°å
Gen.posNumãšGen.negNumã䜿çšããŠãããããæ£ã®æ°ãšè² ã®æ°ãçæã§ããŸãã
 import org.scalacheck.Gen import org.scalacheck.Prop.forAll val negative = Gen.negNum[Int] val positive = Gen.posNum[Int] val propCube = forAll (negative) { x => x * x * x < 0 } 
Gen.chooseNumã«ã¯è峿·±ãæ©èœããããŸãïŒãã®ãžã§ãã¬ãŒã¿ãŒã¯ãæå®ãããç¯å²ïŒå
æ¬çïŒã§ããŒãïŒæå®ãããç¯å²å
ã«åãŸãå ŽåïŒãæå°å€ãšæå€§å€ãããã³æç€ºãããå€ã®ãªã¹ãã®éã¿ã§æ°å€ãçæããŸãïŒ
 
Gen.chooseã䜿çšããŠãç¹å®ã®ç¯å²å
ã®æ°å€ãçæã§ããŸãã ããã«ãããã¯æ±ºããŠå€±æããªããŸããªã¿ã€ãã®ãžã§ãã¬ãŒã¿ãŒã§ãã ã·ã³ãã«ã§ã䜿çšã§ããŸãã ãã£ã©ã¯ã¿ãŒãžã§ãã¬ãŒã¿ãŒãšããã°...
ãã£ã©ã¯ã¿ãŒ
ScalaCheckã«ã¯å€ãã®æåãžã§ãã¬ãŒã¿ãŒããããŸãã æ¬¡ããéžæããããã«æåŸ
ãããŸãã
- Gen.alphaUpperChar
- Gen.alphaLowerChar
- Gen.alphaChar
- Gen.numChar
- Gen.alphaNumChar
ããã§ã¯ããæµ·æŠãã§ã²ãŒã ã®åº§æšãçæããŠã¿ãŸãããã
 val coord = for { letter: Char <- Gen.alphaUpperChar number: Char <- Gen.numChar } yield s"$letter$number" coord.sample  
çè§£ã®ãããã§ããªã¹ããã¿ãã«ãæååãªã©ã®ä»»æã®éèšãçæã§ããŸãã è¡ãšããã°...
è¡
ç°¡åã«çæããããšãã§ããŸãã Gen.alphaStrã¯ãã¢ã«ãã¡ãããæåããã®ã¿æååãçæããŸãã Gen.numStrã¯æ°å€æååãçæããŸãã Gen.alphaLowerStrãšGen.alphaUpperStrãç°ãªãæåããæååãåå¥ã«çæããããšãã§ããŸãGen.alphaLowerStrãšGen.alphaUpperStrã¯ããããã®ç®çã®ããã«èšèšãããŠããŸãã Gen.idenifierã¯ãåžžã«å°æåã®ã¢ã«ãã¡ãããæåã§å§ãŸãããã®åŸã«è±æ°åãç¶ã空ã§ãªãæååãæäŸããŸãã äžéšã®ææ³ã§ã¯ãããã¯éåžžã«èå¥åã§ãã
 import org.scalacheck.Gen val stringsGen = for { key <- Gen.identifier value <- Gen.numStr } yield Bucket(key take 8, value take 2) stringsGen.sample  
æ©èœ
Scalacheckã¯é¢æ°ïŒ Function0ã€ã³ã¹ã¿ã³ã¹ïŒ () => T ïŒãçæã§ããŸãã ãããè¡ãã«ã¯ãæ»ãå€ãçæãããžã§ãã¬ãŒã¿ãŒãGen.function0ãŸãã
 val f = Gen.function0(Arbitrary.arbitrary[Int]).sample //  tostring  ,      - : // some(org.scalacheck.gen$$$lambda$40/1418621776@4f7d0008) 
ã³ã³ããçºé»æ©
arbitraryã䜿çšããŠãæšæºã³ã¬ã¯ã·ã§ã³ã®ã€ã³ã¹ã¿ã³ã¹ãçæã§ããŸãã
 import Arbitrary.arbitrary val listgen = arbitrary[List[Int]] val optgen = arbitrary[Option[Int]] 
ããããããã¯å€ãã®å Žåååã§ã¯ãªããããScalaCheckã¯ã³ã¬ã¯ã·ã§ã³ãšãã®çæãæäœããããã®é«åºŠãªããŒã«ãæäŸããŸãã æ¬¡ã«ã sampleã¡ãœããã«ãã£ãŠè¿ãããOptionãçç¥ãã誀解ãæããªãããã«ãããã«å€ã衚瀺ããŸãã
çæãªãã·ã§ã³
Gen.someã䜿çšãããšããåå
¥ããä¿èšŒãããŸãã
 //     : Gen.some("") // Some() 
ããã«æªãããšã«ããéã«è¿œå ã®èªç±åºŠãããå ŽåïŒ
 // . Gen.option("") // None 
ãªã¹ããšèŸæžãçæããŸã
Gen.listOfã¯ä»»æã®é·ãã®ãªã¹ããçæãã Gen.listOfNã¯æå®ãããé·ãã®ãªã¹ããçæããŸãã
 //  3     Gen[Int]. Gen.listOf(3) map (_ take 5) // List(3, 3, 3, 3, 3) //    . Gen.listOfN(5, Gen.posNum[Double]) map (_ take 5) 
Gen.listOfãžã§ãã¬ãŒã¿ãŒã¯ç©ºã®ãªã¹ããè¿ãå ŽåããããŸãã 空ã§ãªããªã¹ããå¿
èŠã§ããããšãä¿èšŒãããŠããå Žåã¯ã Gen.nonEmptyListOfã䜿çšã§ããŸãã èŸæžãŸãã¯ãããïŒ Map ïŒãçæããã«ã¯ãåæ§ã®ã¡ãœããããããŸãïŒ Gen.mapOf ã Gen.mapOfN ãããã³Gen.nonEmptyMapOfã§ãã ãªã¹ãã¡ãœãããšã¯ç°ãªããèŸæžãžã§ãã¬ãŒã¿ãŒã«ã¯ã2èŠçŽ ã®ã¿ãã«ãžã§ãã¬ãŒã¿ãŒãå¿
èŠã§ãã
 import Arbitrary._ val tupleGen = for { i <- arbitrary[Short] j <- arbitrary[Short] } yield (i, j) Gen.mapOfN(3, tupleGen) map (_ take 3)  
ç¹å®ã®ã»ããã®èŠçŽ ã®ãªã¹ããçæããŸã
Gen.someOfã¯ãæå®ããã»ããã«å«ãŸããç¹å®ã®èŠçŽ ã»ããããArrayBufferãè¿ããŸããæ¬¡ã«äŸã瀺ããŸãã
 import org.scalacheck.Gen.someOf val numbers = someOf(List(1, 2, 3, 4, 5)).sample  
Gen.pickãšåæ§ã«Gen.someOfãŸãã å¯äžã®éãã¯ã Gen.pick䜿çšãããšãå¿
èŠãªèŠçŽ æ°ãæå®ã§ããããšã§ãã
 import org.scalacheck.Gen.pick val lettersGen = Gen.pick(2, List('a', 'e', 'i', 'o', 't', 'n', 'm')).sample  
ã·ãŒã±ã³ã¹ãçæãã
Gen.sequenceã¯ãåãå
¥ããããå€ã®ã·ãŒã±ã³ã¹ã«åºã¥ããŠArrayListãäœæããŸãã æäŸããããžã§ãã¬ãŒã¿ãŒã®å°ãªããšã1ã€ã該åœããå Žåãã·ãŒã±ã³ã¹å
šäœã該åœããŸãã
 import Gen.{const, choose} val ArrayListGen = Gen.sequence(List(const('a'), const('b'), choose('c', 'd')))  
ç¡éã®ã¹ããªãŒã ãçæããŸã
ScalaCheckã¯ãç¡éã¹ããªãŒã ãçæããæ©èœããµããŒãããŠããŸãã
 val stream = Gen.infiniteStream(Gen.choose(0,1))  
ã³ã³ããçºé»æ©
èŸæžãšãªã¹ãã®äžèšã®ã¡ãœããã¯ãå®éã«ã¯ã Gen.containerOfãšãã®ããŒãããŒã䜿çšããç¹æ®ãªã±ãŒã¹ã§ãïŒ containerOfNãšnonEmptyContainerOf`ã ããã¯ãç§ãã¡ãç¥ã£ãŠããã»ãšãã©ã®ã³ã¬ã¯ã·ã§ã³ãçæã§ããæãäžè¬çãªåœ¢åŒã§ãã æ¬¡ã®äŸãèŠãŠã¿ãŸãããã
 import Arbitrary._ //   «»     . val prettyShortSeq = Gen.containerOfN[Seq, Short](3, arbitrary[Short]) // Vector(0, -24114, 32767) //  :  . val genNonEmptyList = Gen.nonEmptyContainerOf[Map[K, V], (K, V)] (oneOf("foo", "bar")) 
containerOfäœæããããžã§ãã¬ãŒã¿ãŒã¯ãåã§ã¯ãªãæœè±¡åã§äœæãããŸãã containerOfã¡ãœããã®ã·ã°ããã£ãèŠãŠã¿ãŸãããã
 def containerOf[C[_],T](g: Gen[T])(implicit evb: Buildable[T,C[T]], evt: C[T] => Traversable[T] ): Gen[C[T]] = 
ãããŠãã®å®è£
ã«ã€ããŠïŒ
 buildableOf[C[T],T](g) 
ãããã£ãŠããªã¹ããŸãã¯* â¶ *ãšããŠè¡šãããšãã§ããäœããçæããå¿
èŠãããå Žåã containerOfã圹ç«ã¡ãŸãã ãããŠã * â¶ * â¶ *ãããªãã®ïŒããšãã°Map ïŒãçæããå¿
èŠãããå Žåã¯ã * â¶ * â¶ *å®è£
ã§èŠãããšãã§ããããã«æœè±¡çãªã¡ãœããã䜿çšããå¿
èŠããããŸãã
 def mapOf[T,U](g: => Gen[(T,U)]) = buildableOf[Map[T,U],(T,U)](g) 
containerã¡ãœãããšåæ§ã«ãã¡ãœããnonEmptyBuildableOf ã nonEmptyBuildableOfããã³nonEmptyBuildableOfãŸãã éåžžãScalacheckã¯ãæž¡ãããã³ã¬ã¯ã·ã§ã³ãåãšããŠæ§ç¯ããæ¹æ³ã決å®ããŸãã ãããè¡ãããã«ãã¿ã€ãorg.scalacheck.util.Buildableæé»çãªã€ã³ã¹ã¿ã³ã¹ã䜿çšããŸãã ãã®ãããªã€ã³ã¹ã¿ã³ã¹ã¯ããã¹ãŠã®æšæºã³ã¬ã¯ã·ã§ã³ã¿ã€ãã®ScalaCheckã§å®£èšãããŸãã Arbitraryã€ã³ã¹ã¿ã³ã¹ãšåæ§ã«ãã³ã¬ã¯ã·ã§ã³ãå®è£
ããŠcontainerOfãµããŒããååŸããã®ã¯ç°¡åã§ãã
é«ãçºé»æ©
芪æãªãèªè
ã®çããã é«éã®æ©èœã¯äœãç¥ã£ãŠãããšæããŸãã ãžã§ãã¬ãŒã¿ãŒã«ãåæ§ã®åäœããããŸãããžã§ãã¬ãŒã¿ãŒã¯ãä»ã®ãžã§ãã¬ãŒã¿ãŒãåŒæ°ãšããŠåãåããä»ã®ãžã§ãã¬ãŒã¿ãŒãçæã§ããŸãã ãŸãã«äŸå€ãé€ããŠã以åã«æ€èšããã³ã³ãããŒãžã§ãã¬ãŒã¿ãŒã髿¬¡ãžã§ãã¬ãŒã¿ãŒã§ãã
å€ãã®äžã€
Gen.oneOfã¯2ããNãžã§ãã¬ãŒã¿ãŒãåãåãããšãã§ããããã«ãã£ãŠæ°ãããžã§ãã¬ãŒã¿ãŒãçæããŸãã
 import Gen.{oneOf, const, choose} //      Gen[T] val dogies = oneOf("Lucy", "Max", "Daisy", "Barney") //        val windows = oneOf(choose(1, 8), const(10)) 
oneOf ããªã¹ããªã©ã®scala.collection.Seqæž¡ãããšãã§ããŸãã
åšæ³¢æ°çºçåš
Gen.frequencyã¯ãå
¥åãšããŠã¿ãã«ã®ãªã¹ããåãå
¥ããŸãã ããããããžã§ãã¬ãŒã¿ãŒãšãã®ç¢ºççéã¿ã§æ§æãããŸãã åºåã¯ãæž¡ãããæŽæ°å€ã確çã®éã¿ãšããŠäœ¿çšããæ°ãããžã§ãã¬ãŒã¿ãŒã§ãã
 val russianLettersInText = Gen.frequency ( (9, ''), (9, ''), (8, ''), (7, ''), (6, '')  
ã¬ã€ãžãŒãžã§ãã¬ãŒã¿ãŒ
Gen.lzyã䜿çšãããšãæ¬åœã«å¿
èŠã«ãªããŸã§çæãé
ããŸãã åæãžã§ãã¬ãŒã¿ãŒããASTãªã©ã®ååž°çãªããŒã¿æ§é ã®çæã«éåžžã«åœ¹ç«ã¡ãŸãã Gen.lzyã䜿çšããå Žåãèšç®ã¯1åå®è¡ãããŸãã Gen.delayèšç®ãGen.delayããæ¯åå®è¡ãããŸãã
çºé»æ©ãµã€ãº
Gen.sizeã¯ãå¯äžã®ãã©ã¡ãŒã¿ãŒãšããŠã©ã ããåãããã©ã¡ãŒã¿ãŒãšããŠæŽæ°ãåããŸãã ãã®æ°å€ã¯ãScalaCheckãå®è¡æã«ç€ºããµã€ãºã§ãã Gen.resize䜿çšGen.resizeãšãå¿
èŠã«å¿ããŠãžã§ãã¬ãŒã¿ãŒã®ãµã€ãºãèšå®ã§ãGen.resize ã ãããæ¬¡ã®äŸã§èª¬æããŸãã
 def genNonEmptySeq[T](genElem: Gen[T]): Gen[Seq[T]] = Gen.sized { size => for { listSize <- Gen.choose(1, size) list <- Gen.containerOfN[Seq, T](listSize, genElem) } yield list } val intVector = genNonEmptySeq(Arbitrary.arbitrary[Int]) val p = Prop.forAll(Gen.resize(5, intVector)) { list => list.length <= 5 } 
ãã§ãã¯ïŒ
 p.check  
Gen.resizeã¯ãæ¢åã®Gen.resizeãããã®ã«åºã¥ããŠæ°ãããžã§ãã¬ãŒã¿ãŒãäœæãGen.resize ã ããã¯ãååž°ãžã§ãã¬ãŒã¿ãŒãäœæãããšããããã³åæã䜿çšããŠåçŽãªãžã§ãã¬ãŒã¿ãŒããè€éãªãžã§ãã¬ãŒã¿ãŒãäœæãããšãã«äŸ¿å©ã§ãã
ãã©ã¯ã¿ã«ãžã§ãã¬ãŒã¿
å€ãã®å Žåãååž°çãªããŒã¿æ§é ãã€ãŸãASTã䜿çšããå¿
èŠããããŸãã . , , , . :
 trait IntTree case class Leaf (value: Int) extends IntTree case class Node (children: Seq[IntTree]) extends IntTree 
:
 import org.scalacheck.Gen._ def treeGen: Gen[IntTree] = oneOf(leafGen, nodeGen) def leafGen: Gen[Leaf] = arbitrary[Int] map (value => Leaf(value)) def nodeGen: Gen[Node] = listOf(treeGen) map (children => Node(children)) 
:
 treeGen.sample Exception in thread "main" java.lang.StackOverflowError at org.scalacheck.ArbitraryLowPriority$$anon$1.arbitrary(Arbitrary.scala:70) at org.scalacheck.ArbitraryLowPriority.arbitrary(Arbitrary.scala:74) at org.scalacheck.ArbitraryLowPriority.arbitrary$(Arbitrary.scala:74) at org.scalacheck.Arbitrary$.arbitrary(Arbitrary.scala:61) 
treeGen . . . treeGen :
 def treeGen: Gen[IntTree] = lzy(oneOf(leafGen, nodeGen)) 
:
 treeGen.sample // Some(Leaf(857998833)) // Some(Leaf(2147483647)) // Some(Leaf(489549235)) 

 Exception in thread "main" java.lang.StackOverflowError at org.scalacheck.rng.Seed.next(Seed.scala:17) at org.scalacheck.rng.Seed.long(Seed.scala:39) at org.scalacheck.Gen$Choose$.org$scalacheck$Gen$Choose$$chLng(Gen.scala:309) at org.scalacheck.Gen$Choose$$anon$5.$anonfun$choose$1(Gen.scala:358) at org.scalacheck.Gen$$anon$3.doApply(Gen.scala:254) at org.scalacheck.Gen.$anonfun$map$1(Gen.scala:75) at org.scalacheck.Gen$$anon$3.doApply(Gen.scala:254) at org.scalacheck.Gen.$anonfun$flatMap$2(Gen.scala:80) at org.scalacheck.Gen$R.flatMap(Gen.scala:242) at org.scalacheck.Gen$R.flatMap$(Gen.scala:239) 
, , . . Gen.sized Gen.resize :
 def nodeGen: Gen[Node] = sized { size => choose(0, size) flatMap { currSize => val nGen = resize(size / (currSize + 1), treeGen) listOfN(currSize, nGen) map (child => Node(child)) } } 
:
 val nGen = resize(size / (currSize + 1), treeGen) 
ããå°ããªãµã€ãºã®æ°ãããžã§ãã¬ãŒã¿ãŒãäœæããŸãïŒãã¹ãã®ã¬ãã«ã«æ¯äŸããŠãµã€ãºãçž®å°ãããŸããç¹å®ã®Nã«å¯ŸããŠãµã€ãº0ã®ç©ºã®ãžã§ãã¬ãŒã¿ãŒãäœæãããã¹ã¿ãã¯ãªãŒããŒãããŒã¯çºçããŸããããžã§ãã¬ãŒã¿ãŒã¯ããã¹ãã®ã¬ãã«ãããããªããããæ¯åãžã§ãââã¬ãŒã¿ãŒã®ãµã€ãºãå°ããããå¿
èŠããããŸãã
ããã§ãååž°çãªãžã§ãã¬ãŒã¿ãŒãèŠã€ããŸãããJSONã®ASTçæã®äŸã¯ãEric TorreborreïŒspecs2ã®äœæè
ïŒããã°ã«ãããŸãã
ããã§ããžã§ãã¬ãŒã¿ãŒãšã®é¢ä¿ãçµäºããããããã£ã«é²ã¿ãŸãããããã®è©³çްã«ã€ããŠã¯ãã·ãªãŒãºã®æ¬¡ã®èšäºã§èª¬æããŸããããããïŒ