免责声明:我不确定我是否真正了解类型上下文界限......或其他任何内容。
是否可以在scala中定义一个类型,该类型是TypeClass的实例,其类型可以是Any,只要该类型服从类型上下文绑定。
例如,我有一些类型Printable[T]
Printable是可以打印的东西的类型类,它作为类型上下文绑定很有用,因为我可能希望类型类可以采用任何类型,只要它是可打印的,就像这样:
class SomeContainer[T: Printable](value: T)
根据我的理解,集合库使用类似这样的上下文边界来处理可以订购,求和等的事情。
但我想要的是type PrintableAnyCollection = SomeCollection[_: Printable]
这是一个可以是不同类型的值的集合,只要所有这些类型都遵守类型上下文绑定,即存在Printable[T]
w / e该类型。
TLDR:
Collection[Any]
几乎可以做我想要的,因为它可以容纳不同的类型
Collection[T: Printable]
几乎可以做我想要的,因为它强制集合中的东西是可打印的,但结果是集合只存储一种类型。
Collection[_: Printable]
和/或Collection[Any: Printable]
看起来像是在描述我想要的但不是有效的语法。
答案 0 :(得分:1)
你可能正在寻找类似的东西:
// Doesn't work
Collection[T forSome {type T: Printable}]
这不起作用,原因是因为上下文边界只是隐式参数的糖,它们在编译时解析。特别是,上述类型意味着编译器所做的隐式解析将取决于上述类型的运行时值(每个不同的T
都需要另一个隐式解析)。实际上,您将创建一个方法,其隐式参数列表中的arity可能会在运行时更改。
我只想说与Scala没什么关系。
另一种方法是主动将隐式参数捆绑在某种包装器类型中,并将包装器上的集合参数化为存在性。因此,在创建集合之前会发生隐式解析。 Miles Sabin很好地涵盖了它here。
简要总结一下这种方法,它看起来如下:
case class PrintableWrapper[T](unwrap: T)(implicit ev: Printable[T])
Collection[PrintableWrapper[T] forSome {type T}]
实际上使用集合的条目很麻烦(需要一个虚假的模式匹配来安抚Scala的类型检查器)。 desugared上下文绑定也需要有一个显式的Printable实例来实际打印条目。有关详细信息,请参阅Miles Sabin的答案。
这恰好是一个地方,其中implicits是一种稍微麻烦的编码类型类的方法。