2017-03-09 8 views
1

上位汎用関数を別の汎用関数にパラメータとして渡そうとしています。しかし、私はそれを機能させることができません。以下は私が達成しようとしているもののサンプルコードです。高次関数をパラメータとして渡すときにスカラのジェネリック型の不一致エラーが発生する

def foo[T](data: Seq[T]) = { 
    //some codes 
} 

def bar[U](id: Sring, fn: Seq[U] => Unit) = { 
    criteria match { 
     case x => data:Seq[String] = //some data; 
       fn(data) 
     case b => data:Seq[Int] = //some data; 
       fn(data) 
     case c => data:Seq[Char] = //some data; 
       fn(data) 
    } 
} 

bar("123", foo) 

私は、コードを実行すると、私はエラーを取得します - 型の不一致を - barをされることは意味がないのSeq [文字列]

答えて

2

val dataことがfnの引数であるので、タイプUでなければなりません:

def bar[U](id: Sring, fn: Seq[U] => Unit) = { 
    val data: Seq[U] = //some data. 
    fn(data) //I want U to be type of data i.e. Seq[String] 
} 

あなたはUStringになりたい場合はbarを呼び出すときに、あなたはそれを指定する必要があります。

bar[String]("123", foo) 

あなたはそれを持っていなければならないタイプbarの内側に決めることができないので、これは実行時に定義されています。常に文字列にしたい場合は、単にUを削除してください。

+0

bar()がfn()を動的に呼び出すとどうなりますか?すなわち、foo()への条件に従って異なるデータ型シーケンスを渡すことができる。 Seq [String]、Seq [Int]、Seq [Char]などを更新しました。 –

+0

@RaKaこれはまったく異なる質問です。あなたはクラスタグが必要です:http://stackoverflow.com/questions/5400394/how-to-get-the-actual-type-of-a-generic-type実際に何を達成しようとしていますか?ジェネリックスを使わなくてもコードを大幅に簡略化することができます – nmat

1

- 配列[U]が見つかりを期待特定のタイプStringを使用しています。 fnSeq[U] => Unitですが、それは非常に具体的なSeq[String]です。 fnU = Stringの場合にのみ機能します。 fnSeq[Int] => Unitの場合はどうなりますか?タイプは一致するとは限りません。

barのボディはfnSeq[String]を受け入れることを期待しているので、あなたが本当に行うことができる唯一のことは、Seq[String] => Unitするfnを必要としています。

def foo[T](data: Seq[T]) = data.foreach(println) 

def bar(id: String, fn: Seq[String] => Unit) = { 
    val data: Seq[String] = List("a", "b", "c") 
    fn(data) 
} 

scala> bar("123", foo) 
a 
b 
c 
+0

bar()が複数の異なるデータ型でfn()を呼び出すとどうなるでしょうか?例えばSeq [Int]と同じように? Can、そうすることができますか?なぜなら、条件に応じて異なるデータ型のシーケンスを生成し、fn()を呼び出すbar関数では一致条件があるからです。 –

関連する問題