【问题标题】:How can I mix higher-kinds with "regular" generics for Typeclasses in Scala如何在 Scala 中将高级类型与“常规”泛型混合用于 Typeclass
【发布时间】:2015-04-28 06:32:54
【问题描述】:

我正在尝试在 scala 中编写自己的 Typeclass,以提供一种将类转换为任意“DataObject”的机制(为此我在下面使用 Map,但我不希望这很重要) .到目前为止,我有以下内容:

type DataObject = Map[String, Any]

trait DataSerializer[A] {
    def toDataObject(instance: A): DataObject
    def fromDataObject(dataObject: DataObject): A
}

这适用于“简单”类,我可以为此创建一个实现此特征的具体类来充当我的序列化程序。但是,我认为允许对集合/容器进行序列化也很好,而不必为可以包含的每种类型创建不同的实现。我最终得到了这个:

trait DataCollectionSerializer[Collection[_]] {
    def toDataObject[A: DataSerializer](instance: Collection[A]): DataObject
    def fromDataObject[A: DataSerializer](dataObject: DataObject): Collection[A]
}

即。如果集合的内容可以序列化,则可以序列化集合。

同样,这适用于大多数事情,但如果我在一个集合中有一个集合怎么办?例如,List[List[Int]](假设存在DataCollectionSerializer[List]DataSerializer[Int] 的一些实现)将需要DataSerializer[List[Int]] 的实现。我可以简单地继续为每个级别的包含编写一个新特征,但这最终会导致我的 Typeclass 可以实现的某个上限。

有没有什么方法可以结合这两个特征,让DataCollectionSerializer 对任何集合进行操作,前提是其内容具有DataSerializerDataCollectionSerializer

【问题讨论】:

    标签: scala generics typeclass higher-kinded-types


    【解决方案1】:

    你可以把DataCollectionSerializer改成

    trait DataCollectionSerializer[Collection[_]] {
      def serializer[A: DataSerializer]: DataSerializer[Collection[A]]
    }
    

    并获得DataSerializer ,例如List[Int]implicitly[DataCollectionSerializer[List]].serializer[Int]。那么所有非高级类型都有DataSerializer,你不需要混合任何东西。

    【讨论】:

    • 我希望有某种方法可以让我拥有ListSerializer extends DataCollectionSerializer[List]DataSerializer[Int],它们可以结合起来处理List[List[ ... List[Int] ... ]],而无需一些特殊的类来处理中间集合.通过这种方式,我可以使用递归方法转换为序列化形式/从序列化形式转换。但是,如果不为每个步骤明确提供一些东西,我似乎无法做到这一点;因为该方法可能需要从上下文中包含任意数量的序列化程序。
    猜你喜欢
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多