微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当只需要一种集合方法时如何使用隐式转换而不是结构类型

如何解决当只需要一种集合方法时如何使用隐式转换而不是结构类型

我有一个方法,在该方法中我只需要访问一种类型的方法appended:+)。我希望能够同时使用自定义案例类和普通的 List。来自 TypeScript 背景,我知道如何使用结构化类型来做到这一点:

case class CustomContainer[T](data: List[T]) {
  def :+(other: T): CustomContainer[T] = copy(data = data :+ other)
}

def append[T,A <: { def :+(other: T): A }](appendable: A,other: T): A = appendable :+ other

append(List(1,2,3),4) // List(1,3,4)
append(CustomContainer(List(1,3)),4) // CustomContainer(List(1,4))

但是,我也知道使用结构类型存在性能和可维护性方面的缺点。我想找到更好的方法,所以我尝试使用特征来做到这一点,但症结在于我不能让 List 扩展我定义的某些特征。我感觉答案是隐式转换,但我不知道如何将某些东西隐式转换为特征,这是一种抽象类型。

这是我迄今为止尝试过的:

trait Appendable[T,C] {
  def :+(other: T): C
}

case class CustomContainer[T](data: List[T]) extends Appendable[T,CustomContainer[T]] {
  override def :+(other: T): CustomContainer[T] = copy(data = data :+ other)
}

implicit def listToAppendable[T](list: List[T]): Appendable[T,List[T]] = ??? // What goes here?

def append[T,A <: Appendable[T,A]](appendable: A,4))

??? 处有什么?或者有没有更好的方法来做到这一点?

我使用的是 Scala 2.10.4。

解决方法

您可以为此使用类型类:

final case class CustomContainer[T](data: List[T])

trait Appendable[T,C[_]] {
  def specialAppend(other: T,acc: C[T]): C[T]
}
object Appendable {
  implicit def listAppendable[A]: Appendable[A,List] = new Appendable[A,List] {
     override def specialAppend(other: A,acc: List[A]): List[A] = other :: acc
  }

  implicit def customContainerAppendable[A]: Appendable[A,CustomContainer] = new Appendable[A,CustomContainer] {
    override def specialAppend(other: A,acc: CustomContainer[A]): CustomContainer[A] = acc.copy(data = other :: acc.data)
  }
}

object Foo {
  implicit class AppendableOps[A,C[_]](val c: C[A]) {
    def :+!(elem: A)(implicit appendable: Appendable[A,C]): C[A] = appendable.specialAppend(elem,c)
  }

  def main(args: Array[String]): Unit = {
    println(List(1,2,3,4) :+! 6)
    println(CustomContainer(List(1)) :+! 2)
    ()
  }
}

产量:

List(6,1,4)
CustomContainer(List(2,1))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。