2016-04-13 7 views
1

ScalaCheckジェネレータは、表現のためのScalaの中でシンタックスシュガーで作業:内部でScalaCheckジェネレータを使用する方法はありますか?

for(s1 <- Gen.choose(1, 10); s2 <- Gen.choose(10, 100)) yield (s1, s2) 

私はScalaCheck式で表現するための「伝統的な」スカラを混在できるようにしたいと思います。たとえば:0 until 10式はGenのタイプではないので、

for(s0 <- 0 until 10; s1 <- Gen.choose(1, 10); s2 <- Gen.choose(10, 100)) yield (s0, s1, s2) 

しかし、これは、コンパイルされません。

同じforループ内でこれを達成するにはどうすればよいですか(一般にSeqおよび/またはTraversableの式)。

編集:答えのコンセンサスは、私が探している統語砂糖の種類は不可能であると思われます。

しかし、これは何らかの形式のステートフルなGenでは実行できないのでしょうか?特に、モナドを使ったのは?

+3

ここで達成しようとしていることは明確ではありません。あなたが目指している表現の_タイプ_は何ですか? –

+0

降伏した式の型がGen [(Int、Int、Int)]であるようにしたいのですが、 ]であるが、s0の値は0から10までの範囲に及ぶが、s1およびs2は毎回ランダムに選択される。 – NietzscheanAI

+0

私は、この範囲からランダムに選択するのではなく、(1〜10)のすべての値が使用されていることを単に「確かめる」ことを望みます。私はそれを行う方法を知らない... –

答えて

2

"従来の" ScalaとScalaCheckの式を組み合わせることができます。

これは実行できません。少なくとも、あなたが示唆しているとおりではありません。あなたにできることは

  • 最初の要素がランダムではない(その代わり、0から10の範囲)において、トリプルの10-長いリスト(長さ10のすなわちリスト)、発生する発電機を定義することです、
  • 私はを想定していジェネレータ実装

10〜100の第三の要素はランダムに選択され
  • 、1〜10秒の要素がランダムに選択されていますが範囲内にあります。

    val listOfPairsGen: Gen[List[(Int, Int)]] = Gen.listOfN(10, pairGen) 
    

    val pairGen: Gen[(Int, Int)] = for { 
        s1 <- Gen.choose(1, 10) 
        s2 <- Gen.choose(10, 100) 
    } yield (s1, s2) 
    
  • は、ペアの10-長いリストのためのジェネレータを定義:

    1. 三重の第二及び第三要素で構成されるペアのためのジェネレータを定義

    2. 定義

      val intList: List[Int] = (0 until 10).toList 
      
    3. の結果と
    4. ジップintList、そして "トリプルに各要素を平らに":

      val myGen: Gen[List[(Int, Int, Int)]] = 
          listOfPairsGen map { list: List[(Int, Int)] => 
          (intList zip list) map { case (a, (b, c)) => (a, b, c) } 
          } 
      

    scala> myGen.sample.head 
    res0: List[(Int, Int, Int)] = List((0,2,58), (1,10,34), (2,3,94), (3,2,91), (4,6,15), (5,7,99), (6,4,82), (7,10,69), (8,8,78), (9,10,27)) 
    
    scala> myGen.sample.get 
    res1: List[(Int, Int, Int)] = List((0,2,56), (1,2,83), (2,4,76), (3,4,87), (4,4,55), (5,6,80), (6,4,94), (7,7,67), (8,10,92), (9,4,84)) 
    
    scala> myGen.sample.get 
    res2: List[(Int, Int, Int)] = List((0,10,40), (1,9,48), (2,10,63), (3,5,100), (4,5,67), (5,4,73), (6,8,56), (7,6,58), (8,6,82), (9,10,86)) 
    
    scala> myGen.sample.get 
    res3: List[(Int, Int, Int)] = List((0,6,56), (1,7,94), (2,4,40), (3,7,27), (4,1,91), (5,3,50), (6,1,70), (7,6,90), (8,7,23), (9,7,49)) 
    
  • +0

    プロパティの検証を '(1〜10).forall {s1 =>' – Aivean

    +1

    @Aivean Trueで囲むことになりますが、プロパティベースのテストのコンテキストでOPがこのジェネレータを必要とするかどうかは不明です。 S /彼は他の目的のためにこの発電機を使いたいかもしれない。 – Jubobs

    1

    Jubobsはすでに説明したように、あなたがすることができません

    ScalaCheck式を使用した式用の "従来の" Scalaを組み合わせる

    ただし、インデックスを使用してやや少ない慣用的なアプローチと説明した結果を達成できます:あなたはいつ、どこで、このようなGeneratorをインスタンス化するためには慎重でなければならないかのように、

    def indexedGenerator = { 
        val index = new AtomicInteger(0) 
        for (s1 <- Gen.choose(1, 10); s2 <- Gen.choose(10, 100)) yield (index.getAndIncrement(), s1, s2) 
    } 
    
    val gen = indexedGenerator 
    println(gen.sample) |-> Some((0,1,60)) 
    println(gen.sample) |-> Some((1,8,82)) 
    println(gen.sample) |-> Some((2,9,29)) 
    println(gen.sample) |-> Some((3,6,76)) 
    println(gen.sample) |-> Some((4,5,32)) 
    

    をカウントvarはすべてのプロパティチェックに対してリセットされません。したがって、インデックスを0から開始する必要があるたびに、新しいローカルインスタンスを作成する必要があります。

    関連する問題