Scala Blog post “Tuples bring generic programming to Scala 3” shows an interesting example of converting a tuple to CSV using new Scala 3 features.
When I try to compile the code from the first part of the blog I am getting error:
no implicit argument of type blog210226.RowEncoder[(String, Int, Boolean)] was found for an implicit parameter of method tupleToCsv in package blog210226
The following import might make progress towards fixing the problem:
import blog210226.TupleEncoders.given_RowEncoder_*:
Here us the code that I copied from the blog (added package
):
package blog210226
trait FieldEncoder[A]:
def encodeField(a: A): String
type Row = List[String]
trait RowEncoder[A]:
def encodeRow(a: A): Row
object BaseEncoders:
given FieldEncoder[Int] with
def encodeField(x: Int) = x.toString
given FieldEncoder[Boolean] with
def encodeField(x: Boolean) = if x then "true" else "false"
given FieldEncoder[String] with
def encodeField(x: String) = x
end BaseEncoders
object TupleEncoders:
// Base case
given RowEncoder[EmptyTuple] with
def encodeRow(empty: EmptyTuple) =
List.empty
// Inductive case
given [H: FieldEncoder, T <: Tuple: RowEncoder]: RowEncoder[H *: T] with
def encodeRow(tuple: H *: T) =
summon[FieldEncoder[H]].encodeField(tuple.head) :: summon[RowEncoder[T]].encodeRow(tuple.tail)
end TupleEncoders
def tupleToCsv[X <: Tuple : RowEncoder](tuple: X): List[String] =
summon[RowEncoder[X]].encodeRow(tuple)
def main(args: Array[String]): Unit =
// This does not compile, why?
val csv = tupleToCsv(("Bob", 42, false))
println(csv)
When I try to add the import suggested in the error:
def main(args: Array[String]): Unit =
import blog210226.TupleEncoders.given_RowEncoder_*:
// This does not compile, why?
val csv = tupleToCsv(("Bob", 42, false))
println(csv)
The error changes to:
no implicit argument of type blog210226.RowEncoder[(String, Int, Boolean)] was found for an implicit parameter of method tupleToCsv in package blog210226.
I found:
blog210226.TupleEncoders.given_RowEncoder_*:[H, T](
/* missing */summon[blog210226.FieldEncoder[String]]
, ???)
But no implicit values were found that match type blog210226.FieldEncoder[String].
val csv = tupleToCsv(("Bob", 42, false))
Am I missing something?