[英]Dependent type constraints (?) on trait in Scala
我有以下 model:
sealed trait MyRequest {
type Response <: MyResponse
}
sealed trait MyResponse {
type Request <: MyRequest
}
case class SayHelloRequest(name: String) extends MyRequest {
override type Response = SayHelloResponse
}
case class SayHelloResponse(greeting: String) extends MyResponse {
override type Request= SayHelloRequest
}
...
有什么方法可以在類型級別強制請求/響應對匹配在一起嗎? 因此,如果SayHelloRequest
的響應類型為SayHelloResponse
,則SayHelloResponse
的請求類型必須為SayHelloRequest
。
就像是:
MyRequest#Response#Request =:= MyRequest
MyResponse#Request#Response =:= MyResponse
嘗試 F 邊界
sealed trait MyRequest { self =>
type This >: self.type <: MyRequest { type This = self.This }
type Response <: MyResponse { type Request = self.This }
}
sealed trait MyResponse { self =>
type This >: self.type <: MyResponse { type This = self.This }
type Request <: MyRequest { type Response = self.This }
}
case class SayHelloRequest(name: String) extends MyRequest {
override type This = SayHelloRequest
override type Response = SayHelloResponse
}
case class SayHelloResponse(greeting: String) extends MyResponse {
override type This = SayHelloResponse
override type Request = SayHelloRequest
}
implicitly[SayHelloRequest#Response#Request =:= SayHelloRequest] // compiles
implicitly[SayHelloResponse#Request#Response =:= SayHelloResponse] // compiles
implicitly[MyRequest#Response#Request <:< MyRequest#This] // compiles
implicitly[MyResponse#Request#Response <:< MyResponse#This] // compiles
或類型 class(和 F 邊界)
// type class
trait RequestResponse {
type Request <: MyRequest[Request]
type Response <: MyResponse[Response]
}
object RequestResponse {
type Req[Rq <: MyRequest[Rq]] = RequestResponse { type Request = Rq }
type Resp[Rsp <: MyResponse[Rsp]] = RequestResponse { type Response = Rsp }
type Aux[Rq <: MyRequest[Rq], Rsp <: MyResponse[Rsp]] =
RequestResponse { type Request = Rq; type Response = Rsp }
// materializers
def req[Rq <: MyRequest[Rq]](implicit
reqResp: RequestResponse.Req[Rq]
): RequestResponse.Aux[Rq, reqResp.Response] = reqResp
def resp[Rsp <: MyResponse[Rsp]](implicit
reqResp: RequestResponse.Resp[Rsp]
): RequestResponse.Aux[reqResp.Request, Rsp] = reqResp
}
sealed abstract class MyRequest[This <: MyRequest[This]](
implicit val reqResp: RequestResponse.Req[This]
) { self: This =>
type Response = reqResp.Response
}
sealed abstract class MyResponse[This <: MyResponse[This]](
implicit val reqResp: RequestResponse.Resp[This]
) { self: This =>
type Request = reqResp.Request
}
case class SayHelloRequest(name: String) extends MyRequest[SayHelloRequest]
case class SayHelloResponse(greeting: String) extends MyResponse[SayHelloResponse]
implicit val sayHelloRequestResponse: RequestResponse.Aux[SayHelloRequest, SayHelloResponse] = null
val rr = RequestResponse.req[SayHelloRequest]
implicitly[rr.Response =:= SayHelloResponse] // compiles
val rr1 = RequestResponse.resp[SayHelloResponse]
implicitly[rr1.Request =:= SayHelloRequest] // compiles
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.