Scala 从某种模式构建类型安全的通用客户机和服务器

Scala 从某种模式构建类型安全的通用客户机和服务器,scala,types,generic-programming,shapeless,Scala,Types,Generic Programming,Shapeless,假设已定义以下架构: object CalculatorSchema { case class AddRequest(x: Int, y: Int) case class AddReply(sum: Int) case class SubtractRequest(x: Int, y: Int)   case class SubtractReply(diff: Int)   // Some code to pair off Requests with respective Repl

假设已定义以下架构:

object CalculatorSchema {
  case class AddRequest(x: Int, y: Int)
  case class AddReply(sum: Int)

  case class SubtractRequest(x: Int, y: Int)
  case class SubtractReply(diff: Int)

  // Some code to pair off Requests with respective Replies
  ...
}
一种可能的映射可能是:

class RR[Req, Rep]
def rr[Req, Rep] = new RR[Req, Rep]()

// within CalculatorSchema, we then define the ff:
val mapping = rr[AddRequest, AddReply] ::
  rr[SubtractRequest, SubtractReply] ::
  HNil // from shapeless
我希望能够以以下方式构建客户端:

val calcClient = RpcGen.createClient(CalculatorSchema)
其中,以下各项应适用:

val r1: AddReply = calcClient.process(AddRequest(1, 2)) // compiles
val r2 = calcClient.process(SomethingElse(99)) // does not compile
我们假设,为了处理请求,所有客户端都会执行以下操作:

def process[Req, Rep](req: Req): Rep = {
  val serialized = serialize[Req](req)
  val rawResponse = sendOverHttpAndAwaitResponse(serialized)
  deserialize[Rep](rawResponse)
}
object CalculatorServer {
  def process(req: AddRequest) = AddReply(req.x + req.y)
  def process(req: SubtractRequest) = SubtractReply(req.x - req.y)
}
另外,我们如何定义一个接受给定模式的服务器?服务器的逻辑应该类似于:

def process[Req, Rep](req: Req): Rep = {
  val serialized = serialize[Req](req)
  val rawResponse = sendOverHttpAndAwaitResponse(serialized)
  deserialize[Rep](rawResponse)
}
object CalculatorServer {
  def process(req: AddRequest) = AddReply(req.x + req.y)
  def process(req: SubtractRequest) = SubtractReply(req.x - req.y)
}
但是我们如何断言
CalculatorServer
应该处理来自
CalculatorSchema
的所有
请求
,并为每个请求返回正确的
回复

此外,我们如何定义以下内容:

RpcGen.startHttpServer(CalculatorSchema, CalculatorServer)
其中,
startServer
的逻辑如下:

def startHttpServer(schema: ???, server: ???): Unit = {
  Http.startServer(9090) { httpReq: HttpReq =>
    val req: ??? = fromHttpReq(httpReq)
    val resp: ???  server.process(req)
    Ok(resp)
  }
}

让你的“模式”成为一种特质。检查你的课本或课堂笔记,那里一定有很多信息。首先提出你自己的解决方案。然后,如果你有任何具体的问题,回来展示你所拥有的。我们可以帮忙。我认为这不是一个容易的问题。考虑一下,我们应该允许映射请求类型到它们各自的响应类型是完全任意的。另外,
calcClient.process
应该是多态的-回复必须是基于输入的正确类型。这在某种程度上是我先前查询的延续:我不知道怎么回事,你觉得“不容易”<代码>def foo(请求:条形):Bat是请求和响应类型之间的映射。