Pangea Pangea - 2 months ago 12
Scala Question

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)

Answer

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.

Comments