Search code examples
scalascalacheck

Type mismatch error in a scala for comprehension


I am writing generators for the following ADTs. Idea is to generate the Blocks with random data. I am having a compiler error Type mismatch: expected: Seq[Field], actual:Gen[Field] in the blockGen method. What am I doing wrong?

EDIT

The error is with fields on the last line of this method i.e. yield Block(id, fields).

def blockGen(b: Block): Gen[Block] = for {
    id <- b.blockId
    fields <- b.fields.map(f => fieldGen(f))
} 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

Generators

def blockGen(b: Block): Gen[Block] = for {
    id <- b.blockId
    fields <- b.fields.map(f => fieldGen(f))
  } yield Block(id, fields)

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)

Solution

  • This is caused by: fieldGen(f) return type is Gen[Field], but your Block fields type is Seq[Field], so compiler throw type mismatch.

    Solution:

    1. change def fieldGen(fieldType: Field): Gen[Field] to def fieldGen(fieldType: Field): Seq[Field], or change Block fields type to Gen[Feild]
    2. create implicit conversion for Gen to Seq, like:

      implicit def genToSeq[T](s: Gen[T]): Seq[T] = ??? // implementation conversion.