【问题标题】:Scala, currying and overloadingScala,柯里化和重载
【发布时间】:2011-11-03 00:01:16
【问题描述】:

假设你有以下几点:

foo(x: String)(y: Int): Int
foo(x: String)(y: Double): Int

Scala 不允许这样的表达。据我所知,原因是 foo("asdf") 没有明确定义的类型(它是 Int => Int 或 Double => Int)。

有什么理由不应该允许这种“多类型”函数吗?

【问题讨论】:

标签: scala types currying


【解决方案1】:

Scala 中的重载解析仅考虑第一个参数列表。这就是为什么这个列表中的替代品必须已经不同的原因。这有一个很好的理由:然后我们可以使用解析函数的类型来推断后续参数的类型。这样可以使用以下成语:

xs.corresponds(ys) { (x, y) => x < y }

注意这里我们需要知道corresponds的类型,以便推断xy的类型。当corresponds 超载时出现这种情况会很遗憾。

【讨论】:

  • 感谢您的回答。作为后续行动,是否有可能根据对应的重载版本在范围内(类似于隐式的工作方式)拥有可以分配给 x 和 y 的可能类型列表,并仅决定只在必要时输入?或者这会违背静态类型的想法吗?
  • 任何考虑可能类型列表的方法都存在类型检查时间呈指数级增长的风险。这就是为什么 Scala 在其类型推断算法中通常不这样做的原因。
【解决方案2】:

这不是第一次被问到:it was asked back in 2009。不幸的是,Martin 没有明确说明问题是什么,只是需要对重载的工作原理进行相当广泛的规范更改。我查看了规范,并不清楚核心问题在哪里,但我对规范的熟练程度不足以给出明确的答案。

【讨论】:

  • 这是一个稍微不同的问题。在您链接到的问题中,您有两个函数,如果我的推理是正确的(仍然不完全相信...),它们的返回类型(foo(x:Bar):Unitfoo(x:Bar):Function1[Bar=&gt;Baz,Unit])只会有所不同。
  • 我不明白为什么 issue 不同。问题出现的条件可能不同,但我认为问题是一样的。我尝试了各种操作,但错误永远不会改变。我读到,重载很早就完成了,或者优先于“x”。
  • 我不确定这是否相同。在您链接到的 scala 问题中,有两个函数是有意义的,因为 foo() 和 foo()_ 是不同的,而在当前情况下,没有不同的方式来表达两种可能的 foo() _ 职能。根本原因可能是相同的,但我不相信。实际上,我认为这也是德克的观点。
【解决方案3】:

一个简单的解决方法是使用匿名对象:

def foo(x: String) = new {
  def apply(y: Int): Int
  def apply(y: Double): Int
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 2018-01-24
    • 2021-02-07
    • 1970-01-01
    • 2011-08-06
    • 2021-03-11
    • 1970-01-01
    相关资源
    最近更新 更多