2016-12-09 7 views
1

のは、私が持っているとしましょう:スカラ:パターン「コンクリート」の場合のために、一般的なケースクラスを一致

sealed trait Data 
final case class TextData() extends Data 
final case class ImageData() extends Data 
final case class MetaData[D <: Data](data: D) extends Data 

私は、パターンマッチデータオブジェクトをしたいです。私が定義されています:

def getDataTypeName(data: Data): String ={ 
    data match { 
     case TextData()=>"text" 
     case ImageData()=>"image" 
     //MetaData(MetaData(_))=>"metaMeta1" //a 
     case _:MetaData[MetaData[_]]=>"metaMeta2" //b 
     //case MetaData(data:Data)=>"meta"+ getDataTypeName(data) //c 
     //MetaData(TextData(_))=>"metaMeta1" //d 
     case MetaData(_)=>"meta" 
    } 
} 

を、私は私のデータがメタメタデータであるかどうかを確認できるようにしたい、メタのTextDataは、など ラインaを言って、私にエラーを与える:

コンストラクタ予想される型にインスタンス化することはできません。見つかった: インスト$ A $ A.MetaData [D]必要:$ A115.this.Dataケース メタデータ(メタデータ(_))=> "metaMeta1"

私は何か似たラインを持っていることを好むだろうa。代わりに、行cのような何かがいいかもしれません。

私はまた、ラインbを試しました。

非可変型引数A $ A115.this.MetaData []で タイプのパターンA $ A115.this.MetaData [A $ A115.this.MetaData []]:この1は、いくつかの警告を生成し、それは消去 場合によって排除されているのでチェックしない です:メタデータ[メタデータ[]] => "metaMeta" ^

私は両方のMetaData[_]sため、この警告が表示されます。私の理解は、上記のパターンは、私のテスト結果と一致するタイプ消去後に_に減少するということです。

私はそのためMetaMetaDataに対してマッチングの方法があるかどうかを知りたい、MetaTextDataMetaMetaMetaDataなど

代わりに、彼らは使用すべきではない方法で密封されたクラスを使用して、私のデザインですか!どのような代替設計をお勧めしますか?

+0

私は、メタデータに対してその試合を想定して、内部クラスを確認するために再び一致すると、あなたの理想的なソリューションではありませんか?データ一致{@}メタデータ(x)=> x一致{...}} '' ' – pedrorijo91

+0

私もそれに満足していると思います。実際に私は何か似たようなことをしようとしましたが(行c)、構文を正しく取得できませんでした。 – ShS

答えて

3

MetaData()の定義に変更を加えてこの作業を行いました。

sealed trait Data 
final case class TextData() extends Data 
final case class ImageData() extends Data 
final case class MetaData(data: Data) extends Data 

def printType(data: Data): String = data match { 
    case TextData()=>"text" 
    case ImageData()=>"image" 
    case MetaData(d)=>"meta:" + printType(d) 
} 

val md = MetaData(MetaData(TextData())) 
printType(md) // res0: String = meta:meta:text 
+0

ああ、私は参照してください。それは私に考えさせます:前の定義とこの定義との間に、コンパイラがそれを見ている点で実際の違いはありますか? – ShS

+0

まあ、当然のことながら、コンパイラは元の定義のもとではコンパイルされないので、違った見方をしています。あなたのコードに違いはありますか?おそらくそうではありません。 – jwvh

+0

私は違いは、古い定義のデータは、それが新しい形式であるのとは対照的にサブタイプとして実際にインターフェースされていたということです。これは基本クラスのインスタンスに過ぎません。しかし、それは実際に重要ですか?あんまり。 – ShS

0
sealed trait Data 
    final case class TextData() extends Data 
    final case class ImageData() extends Data 
    final case class MetaData[D <: Data](data: D) extends Data 

def getDataTypeName(data: Data): String ={ 
    data match { 
     case TextData()=>"text" 
     case ImageData()=>"image" 
     case MetaData(MetaData(_))=> "metaMeta1" 
     case MetaData(TextData())=> "textMeta1" 
     case MetaData(ImageData())=> "imgMeta1" 
    } 
    } 

REPLでのテスト:

scala> getDataTypeName(TextData()) 
res1: String = text 

scala> getDataTypeName(MetaData(TextData())) 
res2: String = textMeta1 

scala> getDataTypeName(MetaData(MetaData(TextData()))) 
res3: String = metaMeta1 
+0

cool!スカラー2.11.7はこれを好まない。 :/ – ShS

+0

本当ですか?エラーは何ですか? – pedrorijo91

関連する問題