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

Ami*_*imi 9 scala type-inference

假设这个功能

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

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

val list = List(1, 2, 3)
func(list, a => a.toString)
Run Code Online (Sandbox Code Playgroud)

但是这个做了:

val list = List(1, 2, 3)
func[Int](list, a => a.toString)
Run Code Online (Sandbox Code Playgroud)

要么

val list = List(1, 2, 3)
func(list, (a: Int) => a.toString)
Run Code Online (Sandbox Code Playgroud)

虽然a类型可以从列表,它是可以推断ListInt.为什么scala不推断这里的类型?

还有其他方法吗?

whe*_*ies 11

还有另一种方式!它也恰好产生了一些很好的合成糖:

def func[A](data: List[A])(mapper: A => String) = data map mapper
Run Code Online (Sandbox Code Playgroud)

看起来像:

func(myList){
  case Left(one) => one
  case Right(_) => default
}
Run Code Online (Sandbox Code Playgroud)

您无法按照预期的方式获取类型信息的原因是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
Run Code Online (Sandbox Code Playgroud)

这也是一个旧的"问题",你可以在这里看到SI-4773.

评论中对Q的回应:

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

func[A, B](data: List[A])(actions: A => B*) = actions map { 
  data map
}
Run Code Online (Sandbox Code Playgroud)

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

func(list)(_.name, _.age, _.sex, _.stalker)
Run Code Online (Sandbox Code Playgroud)

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

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

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