2012-03-30 23 views
7

Biorąc pod uwagę rodzaj Tuplescala typ krotka skład

type T = (String, Int, String) 

Czy jest jakiś sposób mogę uzyskać typu T1, gdzie T1 będzie

type T1 = (MyClass, String, Int, String) 

chciałbym być w stanie zadeklarować klasę jak

class TupleTypes[T] extends AnotherClass[T1] 

Note: wielkość krotka nie jest znana i

type T1 = (MyClass, T) 

nie zwróci tego, co chcę, zwróci (MyClass, (String, Int, String)), który jest inny.

Dzięki

Odpowiedz

5

Moim zdaniem nie istnieją takie konstrukty za krotki, ale HList mieć zachowanie bardzo podobną do tej, którą widać. Uważa się, że ma zaawansowaną strukturę programowania typów, a użycie może być trudne w zależności od tego, co chcesz osiągnąć. Oto excellent starter i nice implementation.

9

Możesz to zrobić, korzystając z HList, aby kumulować konwersje z shapeless.

scala> import shapeless._ ; import Tuples._ 
import shapeless._ 
import Tuples._ 

scala> class MyClass ; val m = new MyClass 
defined class MyClass 
m: MyClass = [email protected] 

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) = ([email protected],foo,23,bar) 
+0

Dzięki Miles, bardzo interesujące. Pytanie brzmi, w jaki sposób uzyskać typ t2 i użyć go do definicji klasy? Jak w powyższym przykładzie "klasa TupleTypes [T] przedłuża AnotherClass [T1]" czy mimo to dostaje T1? – mericano1

+0

Czy możesz podać mi przykłady ogólnych kształtów elementów, które zamierzasz dodać do 'TupleTypes' i' AnotherClass'. Czy mógłbyś też powiedzieć, że potrzebujesz tam jakiejkolwiek użytecznej relacji między 'T' a' T1' (tzn. Czy musisz mieć możliwość skonstruowania wartości typu 'T1' z podanymi wartościami typów' MyClass' oraz 'T' i/lub odwrotnie)? –

+0

Cześć mil, doceniam twoją pomoc. Pracuję ze scalaquery i chcę utworzyć abstrakcyjną klasę bazową, która ma kolumnę typu Long (id). Tak więc 'TupleTypes [T]' jest w rzeczywistości 'BaseTable [T]'. Inne klasy rozszerzające 'BaseTable [T]' będą miały listę kolumn, a typ 'T' będzie krotką jak' (String, Int, Boolean, Date) '. Teraz, ponieważ moja "BaseClass [T]" musi rozszerzyć tabelę scalaquery i dostarczyć krotkę z wszystkimi typami kolumn, 'T1' będzie musiał mieć postać' (Long, String, Int, Boolean, Date) '. Mam nadzieję, że to wyjaśnia, co próbuję osiągnąć. – mericano1

1

późno do partii, ale w przypadku, gdy poszukują „lepsze” rozwiązania w odniesieniu do problemu ScalaQuery, spróbuj tego:

1) utworzyć klasę bazową odwzorowujący z 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) rozciągają odwzorowujący podstawy użyciu klasy przypadku/towarzyszący obiektu (to znaczy nie jest krotką oparciu)

case class Foo (bar: String) 
object Foos extends _Mapper[Foo]("foo") { 
    def foo = column[String]("foo") 
} 

następnie można zrobić coś takiego:

def show: List[Foo] = { 
    val q = (for { f <- Foos } yield f) 

    val foos = db withSession { 
    foos.list map { case t:T => t } 
    } 
    render(foos) 
} 

i mają żeglownych obiekt do pracy z (vs. krotka oparta na indeksie).

Teraz czasami nie potrzebujesz ogromnego wykresu obiektów, gdy potrzebujesz tylko podzestawu pól z grupy obiektów.

To gdzie projekcje przyjść, wystarczy utworzyć klasę case, który reprezentuje zestaw pól, które chcesz i voila, do nawigacji obiekt projekcja do pracy z:

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) 
} 

dość prosta, powinna być zawarta w ciasto DAO napędzane ciastem, ale ogólna zasada brzmi: weź ścieżkę klasy/obiektu.

Należy pamiętać, że ScalaQuery kopie niewiarygodny azz, Zeiger jest genialny! (jak wielu w społeczności Scala, przyszłość wygląda jasno na Scala ;-))