gpt4 book ai didi

Scala 高级类型和协变

转载 作者:行者123 更新时间:2023-12-04 23:18:41 25 4
gpt4 key购买 nike

我试图抽象一些可以返回任何类型的库 API A , Option[A]Seq[A] .

到目前为止,我有这样的事情:

  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[_] 中不起作用不是 covariant 的子类 Seq[_]或类似的东西。但我不确定如何在仍然能够使用的同时解决问题 Const[A] .我绝望了吗?请帮忙。

最佳答案

对于这种类型的多态性,您可以使用 typeclass 概念
考虑

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], 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], Const, X] {
def apply(request: GetOne[X], client: Client): X = client.getOne
}

implicit def handleGetMany[X] = new HandleRequest[GetMany[X], Seq, X] {
def apply(request: GetMany[X], client: Client): Seq[X] = client.getMany
}

关于Scala 高级类型和协变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33317371/

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