我试图将高阶泛型函数作为参数传递给另一个泛型函数。但是,我无法使其发挥作用。以下是我想要实现的示例代码。
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)
如果我运行代码,我将收到错误 - 类型不匹配 - 预期找到Seq [U] - Seq [String]
答案 0 :(得分:2)
val data
必须是U
类型,因为这是fn
的参数:
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]
}
如果您希望U
成为String
,则必须在调用bar
时指定它。
bar[String]("123", foo)
这是在运行时定义的,因此您无法在bar
内部决定它应具有的类型。如果您希望它始终是String,则只需删除U
。
答案 1 :(得分:1)
bar
在使用特定类型String
时是通用的是没有意义的。 fn
是Seq[U] => Unit
,但您传递的是非常具体的Seq[String]
。 fn
仅在U = String
时有效。如果fn
是Seq[Int] => Unit
会怎样?这些类型无法保证匹配。
由于bar
的主体希望fn
接受Seq[String]
,因此您唯一可以做的就是要求fn
为Seq[String] => Unit
。
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