Scala 避免按类型筛选的实例

Scala 避免按类型筛选的实例,scala,functional-programming,shapeless,algebraic-data-types,typesafe,Scala,Functional Programming,Shapeless,Algebraic Data Types,Typesafe,我目前有以下(非类型安全)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

我目前有以下(非类型安全)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())
导入cats.instances.list_
导入cats.syntax.functorFilter_
密封特征枚举类型
案例对象A扩展了枚举类型
案例对象B扩展了枚举类型
案例对象C扩展了枚举类型
密封的抽象类TypeInfo[T Some(info.asInstanceOf[TypeInfo[T]])//不安全
案例=>无
}
}
}
FilterByNumType[A.type](列表(Ainfo(),Binfo(),Ainfo2(),Cinfo())//列表(Ainfo(),Ainfo2())

有没有一种方法可以安全地实现它?typemembers对这类任务有用吗?或者可以使用
无形状的
来实现这一点?

我提出了两种与无形状相关的方法。我不确定这两种方法是否能完全满足您的需要,因为它们取决于提前知道列表中所有元素的类型

假设你有这些东西:

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在用例中看起来不错,但是在未知类型的情况下,我认为
asInstanceOf
并不像一开始看起来那么糟糕…@SomeName correct,如果类型未知,无形状版本将不起作用。这是任何无形状解决方案的典型特征。
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