gpt4 book ai didi

scala - 避免按类型过滤的实例

转载 作者:行者123 更新时间:2023-12-04 08:55:51 26 4
gpt4 key购买 nike

我目前有以下(非类型安全)api,我正在尝试以类型安全的方式重新设计:

import cats.instances.list._
import cats.syntax.functorFilter._


sealed trait EnumType
case object A extends EnumType
case object B extends EnumType
case object C extends EnumType

sealed abstract class TypeInfo[T <: EnumType](val enumType: T)
case class Ainfo() extends TypeInfo(A)
case class Ainfo2() extends TypeInfo(A)
case class Binfo() extends TypeInfo(B)
case class Cinfo() extends TypeInfo(C)

//This is the function implemented in a not typesafe way
def filterByEnumType[T <: EnumType: ClassTag](lst: List[TypeInfo[_]]): List[TypeInfo[T]] = {
lst mapFilter { info =>
info.enumType match {
case _: T => Some(info.asInstanceOf[TypeInfo[T]]) //not type safe
case _ => None
}
}
}

filterByEnumType[A.type](List(Ainfo(), Binfo(), Ainfo2(), Cinfo())) //List(Ainfo(), Ainfo2())
有没有一种方法可以安全地实现它?类型成员是否对此类任务有用或可能 shapeless可以用来吗?

最佳答案

我想出了两种与 shapeless 相关的方法。我不确定两者是否会完全满足您的需求,因为它们取决于提前知道列表中元素的所有类型。
假设你有这个东西:

import shapeless._
import shapeless.ops.hlist._

type HType = TypeInfo[A.type] :: TypeInfo[B.type] :: TypeInfo[A.type] :: TypeInfo[C.type] :: HNil
val hlist: HType = Ainfo() :: Binfo() :: Ainfo2() :: Cinfo() :: HNil
您可以在 HList 上使用过滤器直接地:
hlist.filter[TypeInfo[A.type]] // Ainfo() :: Ainfo2() :: HNil
如果你想避免明确指定 TypeInfo在过滤器调用中,您可以修改过滤器函数(但现在您需要提供 HList 类型——这可以使用代理类解决):
def filterByEnumType[T <: EnumType, L <: HList](
list: L
)(implicit filter: Filter[L, TypeInfo[T]]): filter.Out = {
filter.apply(list)
}

filterByEnumType[A.type, HType](hlist) // Ainfo() :: Ainfo2() :: HNil

关于scala - 避免按类型过滤的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63835437/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com