0
votes

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 }
1
First, can't you please be constructive in finding an answer or just pass by this question? Thanks. Second, I 'd like to use an implicit conversion here to NOT BOTHER the devs with the distinction of the database tuples and the actual entity objects. They should just be able to select what they need and then use it as the entities they like. - Coxer
Declare ls as List[Store] and you should be ready to go, e.g. val ls: List[Store] = query.list. - fotNelton
@Coxer Ok, sorry to come off as harsh. Here goes another try, don't use implicit conversions when explicit is so much clearer, more maintainable, and understandable to others joining a new project. Implicit conversions happen via "magic." Magic code is usually bad. Why not just put the function at the end of the yield and be done with it? - wheaties
To put it in the yield block leaves me with an erro as well - Coxer

1 Answers

2
votes

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.