实现特定类型类的类列表

编程入门 行业动态 更新时间:2024-10-08 12:41:23
本文介绍了实现特定类型类的类列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想定义一个实现公共类型类的元素的List.例如

I would like to define a List of elements implementing a common type class. E.g.

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 实例在范围内?然后我想将这个列表映射到像 list map {_.show} 这样的显示上.

The problem is, how to define a list = List(1, "abc") such that it is guaranteed that a Show instance for these values is in scope? I would then like to map this list over show like list map {_.show}.

推荐答案

我将首先草拟一个解决方案,然后解释为什么使用 List[Any](1, "abc")无法工作.

I will first sketch a solution, and then explain why the naive approach with List[Any](1, "abc") cannot work.

你能做什么

定义一个包装类,可以将 A 类型的实例与 Show[A] 的实例保存在一起:

Define a wrapper class that can hold instances of type A together with instances of Show[A]:

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

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

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

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

Maybe define a separate method to fill this list (consider packing the list itself and the builder-method in a class):

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

或者,您可以小心地添加(范围非常窄的)隐式转换:

Alternatively, you can carefully add a (very tightly scoped) implicit conversion:

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

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

and then costruct your list as follows (note the explicit type ascription):

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

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

Now you can go through the list and call show:

showableList.map(_.show)

获取String的列表.

你不能做什么

你不能简单地定义

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

然后期望能够调用show,因为为了调用Show.show,你需要actual Show实例.这些东西不是一些可以在运行时擦除的类型提示,它们是实际对象,它们必须由编译器提供.一旦你创建了一个List[Any],所有的东西都丢失了,因为所有的类型都被合并成一个无表达的上界Any,编译器没有办法注入所有必要的隐式 Show[T_1],..., Show[T_N].该参数与第三部分非常相似 "定义解释器时处理隐式对于我这个冗长回答的自由单子.

and then expect to be able to call show, because in order to call Show.show, you need actual Show instances. These things are not some type-hints that can be erased at runtime, they are actual objects, and they must be supplied by the compiler. Once you have created a List[Any], all is lost, because all the types are merged into an unexpressive upper bound Any, and the compiler has no way to inject all the necessary implicits Show[T_1],..., Show[T_N]. The argument is very similar to the third section "Dealing with implicits when defining interpreter for the Free monad" of this lengthy answer of mine.

更多推荐

实现特定类型类的类列表

本文发布于:2023-11-25 18:00:33,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1630765.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:类型   列表

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!