Scala Typeclasses与泛型
发布时间:2020-12-16 08:55:17 所属栏目:安全 来源:网络整理
导读:我一直在使用 Scala中的类型类模式,但是当我使用的类型是通用的时,我无法弄清楚如何实现隐式伴随对象. 例如,假设我已经为类型类定义了一个特征,它提供了将东西放入Box中的功能. case class Box[A](value: A)trait Boxer[A] { def box(instance: A): Box[A] d
我一直在使用
Scala中的类型类模式,但是当我使用的类型是通用的时,我无法弄清楚如何实现隐式伴随对象.
例如,假设我已经为类型类定义了一个特征,它提供了将东西放入Box中的功能. case class Box[A](value: A) trait Boxer[A] { def box(instance: A): Box[A] def unbox(box: Box[A]): A } implicit object IntBoxer extends Boxer[Int] { def box(instance: Int) = Box(instance) def unbox(box: Box[Int]) = box.value } def box[A : Boxer](value: A) = implicitly[Boxer[A]].box(value) def unbox[A : Boxer](box: Box[A]) = implicitly[Boxer[A]].unbox(box) 这按预期工作,允许我为各种类型提供Boxer的实现.但是,我不知道如果我希望采取的类型是通用的,我将如何做到这一点.假设我希望能够在任何Seq [A]上使用我的Boxer. Scala中的对象不能包含类型参数,所以我不知道该去哪里: // Will not compile - object cannot have type arguments implicit object SeqBoxer[A] extends Boxer[Seq[A]] { ... } // Will not compile - 'A' is unrecognized implicit object SeqBoxer extends Boxer[Seq[A]] { ... } // Compiles but fails on execution,as this doesn't implement an implicit // conversion for _specific_ instances of Seq implicit object SeqBoxer extends Boxer[Seq[_]] { def box(instance: Seq[_]) = Box(instance) def unbox(box: Box[Seq[_]]) = box.value } // Will not compile - doesn't technically implement Boxer[Seq[_]] implicit object SeqBoxer extends Boxer[Seq[_]] { def box[A](instance: Seq[A]) = Box(instance) def unbox[A](box: Box[Seq[A]]) = box.value } // Compiles,but won't resolve with 'implicitly[Boxer[Seq[Foo]]]' // I had high hopes for this one,too :( implicit def seqBoxer[A]() = new Boxer[Seq[A]] { def box(instance: Seq[A]) = Box(instance) def unbox(box: Box[Seq[A]]) = box.value } 有没有办法支持泛型类型的隐式转换,而不必为每个内部类型隐含一个单独的对象? 解决方法
实际上,你真的很亲密.您需要从seqBoxer [A]中删除括号.否则,编译器将此视为来自()=>的隐式转换. Boxer [Seq [A]],而不仅仅是一个可用的隐含Boxer [Seq [A]].为了更好地衡量,将隐式方法的返回类型显式化也是一个好主意.
implicit def seqBoxer[A]: Boxer[Seq[A]] = new Boxer[Seq[A]] { def box(instance: Seq[A]) = Box(instance) def unbox(box: Box[Seq[A]]) = box.value } scala> box(Seq(1,2,3)) res16: Box[Seq[Int]] = Box(List(1,3)) 您实际上可以使用相同的方法为任何A创建通用Boxer [A],应该要求其行为方式相同. implicit def boxer[A]: Boxer[A] = new Boxer[A] { def box(instance: A): Box[A] = Box(instance) def unbox(box: Box[A]): A = box.value } scala> box("abc") res19: Box[String] = Box(abc) scala> box(List(1,3)) res20: Box[List[Int]] = Box(List(1,3)) scala> unbox(res20) res22: List[Int] = List(1,3) scala> box(false) res23: Box[Boolean] = Box(false) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |