Given a Tuple type
type T = (String, Int, String)
Is there any way I can get a type T1, where T1 would be
type T1 = (MyClass, String, Int, String)
I would love to be able to declare a class like
class TupleTypes[T] extends AnotherClass[T1]
Note: The tuple size is not known and
type T1 = (MyClass, T)
will not return what I want, it will return (MyClass, (String, Int, String)) which is different.
Thanks
You can do this using the HList
to tuple conversions from shapeless.
scala> import shapeless._ ; import Tuples._
import shapeless._
import Tuples._
scala> class MyClass ; val m = new MyClass
defined class MyClass
m: MyClass = MyClass@3859023a
scala> val t1 = ("foo", 23, "bar")
t1: (String, Int, String) = (foo,23,bar)
scala> val t2 = (m :: t1.hlisted) tupled
t2: (MyClass, String, Int, String) = (MyClass@3859023a,foo,23,bar)
In my opinion there are no such constructs for tuples, but HList have a behavior very similar to the one you showed. They are considered has advanced type programming structure, and usage can be difficult depending on what you want to achieve. Here are an excellent starter and a nice implementation.
late to the party, but in the event that you are seeking a "better" solution in regard to the ScalaQuery problem, try this:
1) create mapper base class with ID
import org.scalaquery.ql.extended.{ExtendedTable => Table}
abstract class Mapper[T](table: String) extends Table[T](None, table) {
def id = column[Int]("id", O PrimaryKey)
}
2) extend mapper base using case class/companion object (i.e. not tuple based)
case class Foo (bar: String)
object Foos extends _Mapper[Foo]("foo") {
def foo = column[String]("foo")
}
then you can do something like:
def show: List[Foo] = {
val q = (for { f <- Foos } yield f)
val foos = db withSession {
foos.list map { case t:T => t }
}
render(foos)
}
and have a navigable object to work with (vs. index-based tuple).
Now, sometimes you don't want an enormous object graph when you only need a subset of fields from a group of entities.
That's where projections come in, just create a case class that represents the set of fields that you want and, voila, a navigable projection object to work with:
case class Yum (foo: String, baz: String)
def show: List[Yum] = {
val q = (for { f <- Foos; b <- Bars; if f.id is b.fooID } yield (f.foo, b.baz))
val yums = db withSession {
yums.list map { case t:T => t }
}
render(yums)
}
Fairly simple, should be encapsulated in a cake driven DAO, but the general principle is: take the case class/object route.
Should note that ScalaQuery kicks unbelievable azz, Zeiger is brilliant! (as are many in the Scala community, future is looking bright on Scala way ;-))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With