【问题标题】:Why scala doesn't infer type from generic type parameters?为什么scala不从泛型类型参数推断类型?
【发布时间】:2014-02-04 11:41:53
【问题描述】:

假设这个函数

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 类型可以从List 的Int 列表中推断出来。为什么scala不在这里推断类型?

还有其他方法吗?

【问题讨论】:

    标签: scala type-inference


    【解决方案1】:

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

    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 语句进行模式匹配并提取元组。

    【讨论】:

    • 实际上我的原始方法签名是grid[A](paginated: Paginated[A], columns: Seq[(String, A => String)]),当我将它(如您所说)更改为grid[A](paginated: Paginated[A])(columns: Seq[(String, A => String)]) 时,它起作用了,但调用该方法需要一些额外的括号。像这样的东西:grid(paginated)(Seq(("Name", _.name),("Email", _.email)))。您有减少括号的想法吗?
    • 哇!我的 API 现在非常简洁。非常好。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多