2016-09-13 3 views
1

Как определить генератор для получения случайных данных для fields данного Block. Ниже приведен код лесов. Мне нужна помощь с выражением для замены ???. Это выражение должно генерировать Seq[Field], но Field должен быть сгенерирован с использованием определенной функции genField.Определение генератора ScalaCheck в терминах другого генератора

def blockGen(b: Block): Gen[Block] = for { 
    id <- b.blockId //Use the same blockId as b 
    fields <- ??? //Get the type from each field and call genField 
} yield Block(id, fields) 

ADT

trait Data {} 

trait Field extends Data { 
    val name: String 
    val value: String 
} 

case class StringField(name: String, value: String) extends Field 
case class NumberField(name: String, value: String) extends Field 
case class Block(blockId: Field, fields: Seq[Field]) extends Data 

Генераторы

def fieldGen(fieldType: Field): Gen[Field] = { 
    for { 
    f <- 
    fieldType match { 
     case _: NumberField => numGen 
     case _: StringField => strGen 
    } 
    } yield f 
} 

val strGen: Gen[StringField] = for { 
    name <- Gen.identifier 
    value <- Gen.alphaStr 
} yield StringField(name, value) 

val numGen: Gen[NumberField] = for { 
    name <- Gen.identifier 
    value <- Gen.numStr 
} yield NumberField(name, value) 

Пример Блок: myBlock

val cx = new StringField("blockId", "CX") 
val seg = StringField("segmentation", "ABC") 
val ver = NumberField("version", "1.0") 

val myBlock = Block(cx, Seq(seg, ver)) 

ответ

3

Я считаю, что вы ищете Gen.sequence.

Кроме того, id не должен поступать из генератора, так как все, что вы делаете, использует конкретное значение напрямую.

def blockGen(b: Block): Gen[Block] = 
    for { 
    fields <- Gen.sequence[Seq[Field], Field](b.fields.map(fieldGen)) 
    } yield Block(b.blockId, fields) 

Кстати, Gen.sequence очень похож на Future.sequence и sequence in Haskell.

+0

Интересно, почему я не вижу функцию последовательности в scaladoc: https://www.scalacheck.org/files/scalacheck_2.11-1.13.1-api/index.html#org.scalacheck.Gen –

+1

Это это очень плохой дизайн скаладока, который смущает всех: нажмите «С» в верхнем левом углу (это означает «класс»), и он изменится на «О» (для «объекта»), показывая методы на [сопутствующий объект] (https://www.scalacheck.org/files/scalacheck_2.11-1.13.1-api/index.html#org.scalacheck.Gen$). –

+0

Получил это «O» против «C». Если бы я это знал, я, возможно, попытался бы более решительно решить это :-). –

Смежные вопросы