为什么scala不能从泛型类型参数中推断出类型?

假设这个函数

def func[A](data: List[A], mapper: A => String) = { 
  data.map(item => mapper(item)) 
}

为什么这段代码不能编译:

val list = List(1, 2, 3)
func(list, a => a.toString)

但是这个确实如此:

val list = List(1, 2, 3)
func[Int](list, a => a.toString)

要么

val list = List(1, 2, 3)
func(list, (a: Int) => a.toString)

虽然a类型可以从列表中可以推断这是ListInt 。 为什么scala不能在这里推断这种类型?

有没有其他方法?


还有另一种方式! 它也恰好为一些很好的合成糖做出了贡献:

def func[A](data: List[A])(mapper: A => String) = data map mapper

这看起来像:

func(myList){
  case Left(one) => one
  case Right(_) => default
}

您无法按照您期望的方式获取类型信息的原因在于,Scala中的类型信息保持不变。 在其他系统中,类型信息是已知的,并根据定义的用途进行推导。 你有时必须解决这些限制,但同时,在这种情况下,你可以开始使用类似于你自己定义的控制结构的东西。

所以...

func[Int]( //I've just told the typer what the information is and it can flow to the right.
func(list //the typer has to deduce the type and without a guide can not figure out what a => a.toString should be

这也是一个老问题,你可以在这里看到SI-4773。

在评论中对Q的回应

如果你想有一个Seq[A => B]那么我会做类似的事情

func[A, B](data: List[A])(actions: A => B*) = actions map { 
  data map
}

这是使用可变参数(转换为WrappedArray ,因此map )接受任何命令列表,以便您可以传递是

func(list)(_.name, _.age, _.sex, _.stalker)

至于拉出并匹配你所传递的内容:

func[A, B](data: List[A])(actions: (String, A => B)*) = actions map { 
  case (name, f) => (name, data map f)
}

其中你正在使用case语句来模式匹配并提取元组。

链接地址: http://www.djcxy.com/p/38017.html

上一篇: Why scala doesn't infer type from generic type parameters?

下一篇: Scala type inference on an existential type