2016-04-19 13 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は常にMessagesTypeに種類ごとのOption Sが含まれています:私は現在、このようなものを持っています。私は、SubMessagesTypeしか宣言しておらず、対応するAggregatorTypeが自動的に生成される方法を見てきました。現在私はTupleを使っていますが、HList、ケースクラスなどに変更できます。しかし、私は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 2.xではなくShapeless 1.2.4を使用しなければなりません。( –

+0

これを1.2.4に変換することが可能であると思います( '.tupled'、' .hlisted'、 'Mapped 'は1.2.3で追加されました)。 –