0

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 }
4
  • 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. Commented Jan 16, 2014 at 14:20
  • Declare ls as List[Store] and you should be ready to go, e.g. val ls: List[Store] = query.list. Commented Jan 16, 2014 at 14:29
  • @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? Commented Jan 16, 2014 at 14:37
  • To put it in the yield block leaves me with an erro as well Commented Jan 16, 2014 at 15:37

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

And this can be accomplished using another converstion?
The two lines of code I've given don't need another conversion. If you want to keep your own line, you can add the conversion I've listed above. And then another conversion for map (though they can be unified), another for flatMap, etc.
Okay, I understand the two lines you have given. But what I don't understand is the conversion you listed above. What should the actual code look like? Can u write it out?
So am I correct, if I say that the convertLambdasWithStoreArguments conversion converts the lambda Store => A to a lambda StoreTuple => A? If yes, is it then also correct the the Tuple2Store conversion is later used to convert the StoreTuple to a Store in order to match to the parameter type requirements of f in the convertLambdasWithStoreArguments?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.