加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 实现某个类型类的类列表

发布时间:2020-12-16 19:20:36 所属栏目:安全 来源:网络整理
导读:我想定义一个实现公共类型类的元素列表.例如. trait Show[A] { def show(a: A): String } implicit val intCanShow: Show[Int] = new Show[Int] { def show(int: Int): String = s"int $int" } implicit val stringCanShow: Show[String] = new Show[String]
我想定义一个实现公共类型类的元素列表.例如.

trait Show[A] {
    def show(a: A): String
  }
  implicit val intCanShow: Show[Int] = new Show[Int] {
      def show(int: Int): String = s"int $int"
  }
  implicit val stringCanShow: Show[String] = new Show[String] {
    def show(str: String): String = str
  }

问题是,如何定义list = List(1,“abc”),以确保这些值的Show实例在范围内?然后,我想将此列表映射到show list list {_.show}.

解决方法

我将首先草拟一个解决方案,然后解释为什么使用List [Any](1,“abc”)的天真方法无效.

你可以做什么

定义一个包装类,它可以包含类型A的实例以及Show [A]的实例:

case class Showable[A](a: A,showInst: Show[A]) {
  def show: String = showInst.show(a)
}

将列表定义为List [Showable [_]]:

var showableList: List[Showable[_]] = Nil

也许定义一个单独的方法来填充这个列表(考虑将列表本身和类中的builder-method打包):

def addShowable[A: Show](a: A): Unit = {
  showableList ::= Showable[A](a,implicitly[Show[A]])
}

或者,您可以仔细添加(非常严格范围的)隐式转换:

implicit def asShowable[A](a: A)(implicit s: Show[A]): Showable[A] = 
  Showable(a,s)

然后按如下方式构建列表(请注意显式类型归属):

val showableList = List[Showable[_]](1,"abc")

现在您可以浏览列表并调用show:

showableList.map(_.show)

获取String列表.

你不能做什么

你不能简单地定义

val list: List[Any] = List(1,"abc",<showable3>,...,<showableN>)

然后期望能够调用show,因为为了调用Show.show,您需要实际的Show实例.这些东西不是可以在运行时擦除的某些类型提示,它们是实际对象,它们必须由编译器提供.一旦你创建了List [Any],一切都会丢失,因为所有类型都被合并到一个未表达的上限Any,并且编译器无法注入所有必要的含义Show [T_1],…,Show [ T_N.该论点与第三部分“Dealing with implicits when defining interpreter for the Free monad” of this lengthy answer of mine非常相似.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读