使用`implicit def`制作类型类实例?

Kev*_*ith 1 scala typeclass

鉴于:

scala> trait Resource[A] { def f: String }
defined trait Resource

scala> case class Foo(x: String)
defined class Foo
Run Code Online (Sandbox Code Playgroud)

然后暗示:

scala> implicit def fooToResource(foo: Foo): Resource[Foo] = 
        new Resource[Foo] { def f = foo.x }
Run Code Online (Sandbox Code Playgroud)

以下作品:

scala> implicitly[Resource[Foo]](Foo("foo")).f
res2: String = foo
Run Code Online (Sandbox Code Playgroud)

我定义了一个函数:

scala> def f[A](x: A)(implicit ev: Resource[A]): String = ev.f
f: [A](x: A)(implicit ev: Resource[A])String
Run Code Online (Sandbox Code Playgroud)

但是,以下代码无法编译:

scala> f(Foo("foo"))
<console>:17: error: could not find implicit value for parameter ev: Resource[Foo]
       f(Foo("foo"))
Run Code Online (Sandbox Code Playgroud)

其次,我尝试过:

scala> f2(Foo("bippy"))
<console>:17: error: could not find implicit value for parameter ev: Resource[Foo]
       f2(Foo("bippy"))
        ^
Run Code Online (Sandbox Code Playgroud)

最后,我试图:

scala> def g(foo: Foo)(implicit ev: Resource[Foo]): String = ev.f
g: (foo: Foo)(implicit ev: Resource[Foo])String

scala> g(Foo("5"))
<console>:17: error: could not find implicit value for parameter ev: Resource[Foo]
       g(Foo("5"))
        ^
Run Code Online (Sandbox Code Playgroud)

但是,它也失败了.我该怎么f办?

Did*_*ont 5

好的,Peter Neyens的回答,这不是一个类型类,这是一个隐式转换,你应该避免 - 应该有一些警告,要求你导入scala.language.implicitConversions.

作为补充,这就是为什么第一个implicitly有效:

隐含的只是:

def implicitly[T](implicit ev: T): T = e
Run Code Online (Sandbox Code Playgroud)

implicitly[T] 不提供参数的情况下编写时,它将T在范围中查找隐式类型并返回它.但是,你用一个参数隐式调用(我相信没有正当理由这样做,所以它只会返回你的参数Foo("foo"),一个实例)Foo.除非您明确声明T应该是Resource [Foo].如果您已经编写了类型归属,例如(Foo("foo"): Resource[Foo]),它将以相同的方式工作.implicitly与此无关.

关键是Foo("foo")不是预期的类型Resource[Foo],而只是一个Foo.编译器会拒绝它,除了此时,您在上面定义的隐式转换启动,并且您的Foo实例转换为Resource[Foo].然后,你可以打电话f.

接下来,你打电话给你f(Foo("foo")).有一个隐含参数,但是这次你不提供它.所以编译器会查找一个(虽然它第一次没有这样做),并且因为没有这样的实例,所以失败了.

  • @KevinMeredith没有理由使用显式参数调用`implicitly`,如`hiddenly [Resource [Foo]](Foo("foo"))`. (2认同)