2012-04-03 10 views
2

私はScala Id型の型定義を作成したいと思います。例えば、Foo型のIdがLong型の値をとることを宣言できます。スカラーコンパイラは、あるタイプを他のタイプから推測させるにはどうすればよいですか?

val fooId: Id[Foo] = Id(12L) // type-safe at compile time 
val fooIdValue: Long = fooId.value // able to get the value back out 

私はさまざまな方法を試しましたが、私は制約を適用できないようです。私は

trait WithId[I] { 
    type Id = I 
} 

case class Id[A <: WithId[_]](value: A#Id) // A#Id => Any, not what I want! 

class Foo extends WithId[Long] { 
    type Id = Long 
} 

を宣言した場合、私はWithIdその後

val fooId: Id[Foo] = Id(12L) 

がコンパイルできない抽象型

trait WithId { 
    type Id 
} 

case class Id[A <: WithId](value: A#Id) 

class Foo extends WithId { 
    type Id = Long 
} 

を使用するように変更した場合、これは

を言って、

val fooId: Id[Foo] = Id("foo") // should be illegal unless a Long 

することができます

no type parameters for method apply: (value: A#Id)net.box.Id[A] in object Id exist so that it can be applied to arguments (Long) --- because --- argument expression's type is not compatible with formal parameter type; found : Long required: ?0A#Id 

Id [Foo]がLongを取るとはどういうふうに言いますか?

答えて

3

WithIdにそのタイプのパラメータを削除するのは当然です。ただし、発生する2番目の問題は、Idのインスタンス化の結果に起因します。 val x: Foo[T]と言うときは、xのタイプを指定していますが、構築時にどのタイプのものを使用すればよいかをコンパイラに教えているわけではありません。だからコンパイルエラーはIdからAのうちFooになると言いますが、Fooには何も言わなかったのですが、結果はAです。修正するには、使用方法を

val fooId = Id[Foo](12L) 
+0

に変更するだけです。私は "タイプを切り替える"とは思っていませんでした。もしそれが左側にあれば、それは右側に挿入されると思います。ありがとう! –

関連する問題