scala – 实现某个类型类的类列表
我想定义一个实现公共类型类的元素列表.例如.
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非常相似. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |