2016-04-19 56 views
1

是否有一種以通用方式轉換類型的方法?目前,我有這樣的事情:一般在Scala中轉換類型

class Super { 
    type MessagesType = Product 
    type AggregatorType = Product 
} 

class Sub1 { 
    override type MessagesType = (Class1, Class2) 
    override type AggregatorType = (Option[Class1], Option[Class2]) 
} 

class Sub2 { 
    override type MessagesType = (Class1, Class2, Class3) 
    override type AggregatorType = (Option[Class1], Option[Class2], Option[Class3]) 
} 

AggregatorType將始終包含在MessagesTypeOption s各自的類型的。我一直在尋找僅在Sub中聲明MessagesType並自動生成相應的AggregatorType的方法。雖然我目前使用Tuple s,但我可以將其更改爲HList s,case classes或其他。但是,我確實有使用Shapeless 1.2.4的限制(由於一些傳遞依賴性)。

任何想法?

回答

0

您可以使用形狀爲Mapped的類型。

讓編譯器推斷大部分類型是有點困難。我使用了一個嵌套類,也許別人可以想出一個更漂亮的解決方案。

import shapeless._ 
import shapeless.ops.hlist.{Mapped, Tupler} 

class WithMessage[Message <: Product] { 
    class Super[ 
    G <: HList, 
    M <: HList, 
    T <: Product 
    ](implicit 
    gen: Generic.Aux[Message, G], // from tuple to generic (HList) representation 
    map: Mapped.Aux[G, Option, M], // all elements of the G HList in an Option 
    tup: Tupler.Aux[M, T]   // from HList M back to a tuple 
) { 
    type Aggregator = T 
    // ... 
    } 
} 

哪些可以作爲:

val StringIntMsg = new WithMessage[(String, Int)] 
object SI extends StringIntMsg.Super 

val si: SI.Aggregator = (Some("foo"), Some(1)) 
+0

這看起來很有趣......但有一個額外的問題。由於一些傳遞依賴性,我必須使用Shapeless 1.2.4,而不是無形2.x :( –

+0

我認爲應該可以將其轉換爲1.2.4(它具有'.tupled','.hlisted'和'Mapped '它在1.2.3中加入)。 –