gpt4 book ai didi

scala - 关于隐式的奇怪错误消息

转载 作者:行者123 更新时间:2023-12-04 15:26:04 25 4
gpt4 key购买 nike

scala> implicit def transitive[A, B, C](implicit f: A => B, g: B => C): A => C = f andThen g
transitive: [A, B, C](implicit f: A => B, implicit g: B => C)A => C

scala> class Foo; class Bar; class Baz { def lol = println("lol") }
defined class Foo
defined class Bar
defined class Baz

scala> implicit def foo2Bar(f: Foo) = new Bar
foo2Bar: (f: Foo)Bar

scala> implicit def bar2Baz(f: Bar) = new Baz
bar2Baz: (f: Bar)Baz

scala> implicitly[Foo => Baz]
<console>:14: error: diverging implicit expansion for type Foo => Baz
starting with method transitive in object $iw
implicitly[Foo => Baz]

从上面的代码中应该很明显,我正在尝试编写一个方法,当在作用域中导入时,它将使隐式转换具有可传递性。我期待这段代码可以工作,但令人惊讶的是它没有。上面的错误消息是什么意思,我怎样才能使这段代码工作?

最佳答案

更新:正如评论中所指出的,这种方法不能在 2.8 上编译,而 implicitly[Foo => Baz]工作正常,(new Foo).lol没有。

如果您重命名 transitive,这会很好用至 conforms隐藏 Predef 中的方法:

implicit def conforms[A, B, C](implicit f: A => B, g: B => C): A => C = f andThen g

this answer更多细节。

附带说明:从 -Xlog-implicits 开始 REPL是在这种情况下获取更多信息性错误消息的便捷方式。在这种情况下,一开始并没有太大帮助:
scala> implicitly[Foo => Baz]
scala.this.Predef.conforms is not a valid implicit value for Foo => Baz because:
type mismatch;
found : <:<[Foo,Foo]
required: Foo => Baz
<console>:14: error: diverging implicit expansion for type Foo => Baz
starting with method transitive in object $iw
implicitly[Foo => Baz]
^
scala.this.Predef.conforms is not a valid implicit value for Foo => Baz because:
type mismatch;
found : <:<[Foo,Foo]
required: Foo => Baz
transitive is not a valid implicit value for Unit => Foo => Baz because:
not enough arguments for method transitive: (implicit f: A => B, implicit g: B => C)A => C.
Unspecified value parameter g.
transitive is not a valid implicit value for => Unit => Foo => Baz because:
not enough arguments for method transitive: (implicit f: A => B, implicit g: B => C)A => C.
Unspecified value parameter g.

但是如果我们暂时改写 foo2Barbar2Baz作为函数,我们会收到一条错误消息,突出显示了歧义:
implicit val foo2Bar = (_: Foo) => new Bar
implicit val bar2Baz = (_: Bar) => new Baz

scala> implicitly[Foo => Baz]
transitive is not a valid implicit value for Foo => Baz because:
ambiguous implicit values:
both method conforms in object Predef of type [A]=> <:<[A,A]
and value foo2Bar in object $iw of type => Foo => Bar
match expected type Foo => B

现在很明显我们只需要阴影 conforms .

关于scala - 关于隐式的奇怪错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7940726/

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