Question

I can't get the following code with the included implicit working. The variable ls contains a list of tuples like defined in the Tuple2Store implicit. My foreach lamda argument requires the members of the list to be instances of the class Store. So why does the implicit conversion not kick in?

  implicit def Tuple2Store(tuple: (Int, Option[Date], Option[String], Option[Date], Option[Boolean], Option[Boolean],
      Option[Boolean], Option[Boolean], Option[String])): Store =
      { new Store(tuple._1, tuple._2, tuple._3, tuple._4, tuple._5, tuple._6, tuple._7, tuple._8, tuple._9) }

  val entities = TableQuery[StoreTable]
  val query = for {
    c <- entities if c.costCenterNumber === 60506
  } yield (c)

  val ls = query.list

  ls.foreach((s: Store) => println(s.toString))

Following error message is displayed:

  • type mismatch; found : datamodel.Store => Unit required: ((Int, Option[java.sql.Date], Option[String], Option[java.sql.Date], Option[Boolean], Option[Boolean], Option[Boolean], Option[Boolean], Option[String])) => ?

Edit: The following code leaves me with a List of Store instances in the ls variable... this is what I wanted to accomplish, but is there an easier way?

  implicit def Tuple2Store(tuple: (Int, Option[Date], Option[String], Option[Date], Option[Boolean], Option[Boolean],
      Option[Boolean], Option[Boolean], Option[String])): Store =
      { new Store(tuple._1, tuple._2, tuple._3, tuple._4, tuple._5, tuple._6, tuple._7, tuple._8, tuple._9) }

  val entities = TableQuery[StoreTable]
  val query = for {
    c <- entities if c.costCenterNumber === 60506
  } yield (c)

  val ls = query.list.map { Tuple2Store }
Was it helpful?

Solution

Because implicits don't work like this. You have a conversion from (Int, Option[Date], Option[String], Option[Date], Option[Boolean], Option[Boolean], Option[Boolean], Option[Boolean], Option[String]) to Store, but you want a conversion from Store => Unit to (Int, Option[Date], Option[String], Option[Date], Option[Boolean], Option[Boolean], Option[Boolean], Option[Boolean], Option[String]) => Unit:

// just to simplify
type StoreTuple = (Int, Option[Date], Option[String], Option[Date], 
  Option[Boolean], Option[Boolean], Option[Boolean], Option[Boolean], Option[String])

// uses the conversion you've already defined
implicit def convertLambdasWithStoreArguments[A](f: Store => A): StoreTuple => A = 
  tuple => f(tuple) 

But then you may find that you need, e.g. conversion from List[StoreTuple] to List[Store], from Map[Store, A] to Map[StoreTuple, A], and so on.

Instead of defining all these additional conversions, you may use your existing one and write

ls.foreach { s => val store: Store = s; println(store.toString) }

instead. Or

ls.foreach { s => println(s.asString) }

where asString is a method of Store. Note that

ls.foreach { s => println(s.toString) }

won't work since Tuple9 already has a toString method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top