Scala更高级的类型和协变
发布时间:2020-12-16 09:51:12 所属栏目:安全 来源:网络整理
导读:我试图抽象出一些可以返回A,Option [A]或Seq [A]类型的库API. 到目前为止,我有这样的事情: type Const[T] = T sealed abstract class Request[F[_],A] case class GetOne(id: Int) extends Request[Const,Int] case class GetMany() extends Request[Seq,St
我试图抽象出一些可以返回A,Option [A]或Seq [A]类型的库API.
到目前为止,我有这样的事情: type Const[T] = T sealed abstract class Request[F[_],A] case class GetOne(id: Int) extends Request[Const,Int] case class GetMany() extends Request[Seq,String] 然后当我使用它时: def get[F[_],A](request: Request[F,A]): F[A] = request match { case GetOne(id) => client.getOne[F[A]](id) case GetMany() => client.getMany[A]() // error: Seq[A] does not conform to F[A] } 我理解为什么这不起作用,因为F [_]不是协变Seq [_]的子类或类似的东西.但是我不知道如何在能够使用Const [A]的情况下解决这个问题.我绝望了吗?请帮忙. 解决方法
对于这种类型的多态,您可以使用类型类概念
考虑到 trait Client { def getOne[X]: X def getMany[X]: Seq[X] } type Const[T] = T sealed abstract class Request[F[_],A] case class GetOne(id: Int) extends Request[Const,Int] case class GetMany() extends Request[Seq,String] 我们可以定义这样的类型类: trait HandleRequest[R <: Request[F,A],F[_],A] { def apply(request: R,client: Client): F[A] } 并针对所需案例进行实例化: implicit object handleGetOne extends HandleRequest[GetOne,Const,Int] { def apply(request: GetOne,client: Client): Int = client.getOne } implicit object handleGetMany extends HandleRequest[GetMany,Seq,String] { def apply(request: GetMany,client: Client): Seq[String] = client.getMany } 现在您可以按如下方式定义常规函数: implicit class ClientOps(val client: Client) { def get[R <: Request[F,A](request: R)(implicit handle: HandleRequest[R,F,A]): F[A] = handle(request,client) } 如果您想要概括您的请求类型,例如: case class GetOne[X](id: Int) extends Request[Const,X] case class GetMany[X]() extends Request[Seq,X] 您可以将实例重新定义为: implicit def handleGetOne[X] = new HandleRequest[GetOne[X],X] { def apply(request: GetOne[X],client: Client): X = client.getOne } implicit def handleGetMany[X] = new HandleRequest[GetMany[X],X] { def apply(request: GetMany[X],client: Client): Seq[X] = client.getMany } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |