gpt4 book ai didi

scala - 如何将类型类模式与子类型相结合?

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

假设我在 Scala 中使用 typeclass 模式。这是我如何制作 C 类
类型类 Foo 的一部分:

Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26).

scala> trait Foo[T] { def foo(t: T) }
defined trait Foo

scala> def foo[T : Foo](t: T) { implicitly[Foo[T]].foo(t) }
foo: [T](t: T)(implicit evidence$1: Foo[T])Unit

scala> class C
defined class C

scala> foo(new C)
<console>:11: error: could not find implicit value for evidence parameter of type Foo[C]
foo(new C)
^

scala> implicit object FooC extends Foo[C] { override def foo(c: C) { println("it's a C!") } }
defined module FooC

scala> foo(new C)
it's a C!

到现在为止还挺好。但是假设我有 C 的子类 D,并且我希望 D 的实例也“在”类型类中:
scala> class D extends C
defined class D

scala> foo(new D)
<console>:13: error: could not find implicit value for evidence parameter of type Foo[D]
foo(new D)
^

哦!如何在不必为 D 显式提供类型类实例的情况下完成这项工作?

最佳答案

对此有不同的可能解决方案,这取决于我是否只想为 C 解决问题,或者我是否想为整个类型类解决问题。

仅适用于 C,而不是 implicit object FooC ...我们说:

implicit def CIsFoo[T <: C]: Foo[T] =
new Foo[T] { override def foo(t: T) { println("it's a C!") } }

要修复所有 Foo,请使其逆变:
trait Foo[-T] { def foo(t: T) }

或者如果由于某种原因你不能或不想这样做,你可以替换 def foo...和:
def foo[T](t: T)(implicit foo: Foo[_ >: T]) =
foo.foo(t)

(感谢#scala 居民 Daniel Sobral 和 Stefan Zeiger 的帮助。)

更新 2011 年 9 月 20 日包含我错过的“make Foo逆变”解决方案

关于scala - 如何将类型类模式与子类型相结合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6682824/

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