gpt4 book ai didi

scala - 当类型已知时,为什么对重载定义的引用不明确?

转载 作者:行者123 更新时间:2023-12-03 02:42:06 24 4
gpt4 key购买 nike

我有一个像这样的函数:

def ifSome[B, _](pairs:(Option[B], B => _)*) {
for((paramOption, setFunc) <- pairs)
for(someParam <- paramOption) setFunc(someParam)
}

以及像这样的重载函数:

class Foo{ 
var b=""
def setB(b:String){this.b = b}
def setB(b:Int){this.b = b.toString}
}

val f = new Foo

然后下面的行会产生错误:

ifSome(Option("hi") -> f.setB _)

<console>:11: error: ambiguous reference to overloaded definition,
both method setB in class Foo of type (b: Int)Unit
and method setB in class Foo of type (b: String)Unit
match expected type ?
ifSome(Option("hi") -> f.setB _)

但是编译器知道我们正在寻找 Function1[java.lang.String, _],那么为什么 Function1[Int, _] 的存在会带来任何困惑呢?我是否遗漏了一些东西,或者这是一个编译器错误(或者也许它应该是一个功能请求)?

我能够通过使用像这样的类型注释来解决这个问题

ifSome(Option("hi") -> (f.setB _:String=>Unit))

但我想了解为什么这是必要的。

最佳答案

您需要尝试$ scalac -Ydebug -Yinfer-debug x.scala,但首先您需要最小化。

在这种情况下,您将看到在柯里化(Currying)版本中如何在第一个参数列表中求解 B:

[infer method] solving for B in (bs: B*)(bfs: Function1[B, _]*)Nothing 
based on (String)(bfs: Function1[B, _]*)Nothing (solved: B=String)

对于未柯里化(Currying)的版本,你会发现一些奇怪的地方

[infer view] <empty> with pt=String => Int

因为它试图消除过载的歧义,这可能会导致您得到下面奇怪的解决方案。

虚拟隐式的唯一目的是解决过载,以便推理可以继续进行。隐式本身未使用且未实现???

这是一个非常奇怪的解决方案,但你知道重载是邪恶的,对吧?你必须使用你可以使用的任何工具来对抗邪恶。

另请注意,您的类型注释解决方法比仅以正常方式指定类型参数更加费力。

object Test extends App {
def f[B](pairs: (B, B => _)*) = ???
def f2[B](bs: B*)(bfs: (B => _)*) = ???

def g(b: String) = ???
def g(b: Int) = ???

// explicitly
f[String](Pair("hi", g _))

// solves for B in first ps
f2("hi")(g _)

// using Pair instead of arrow means less debug output
//f(Pair("hi", g _))

locally {
// unused, but selects g(String) and solves B=String
import language.implicitConversions
implicit def cnv1(v: String): Int = ???
f(Pair("hi", g _))
}

// a more heavy-handed way to fix the type
class P[A](a: A, fnc: A => _)
class PS(a: String, fnc: String => _) extends P[String](a, fnc)
def p[A](ps: P[A]*) = ???
p(new PS("hi", g _))
}

关于scala - 当类型已知时,为什么对重载定义的引用不明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12648019/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com