Scala中高类类型参数恒等式的类型推理

k97glaaz  于 2022-11-09  发布在  Scala
关注(0)|答案(1)|浏览(161)

我有一堂打字课

trait ResponseHandler[+A, -B[_]] {
  def handle[C](response: WSResponse, parser: A => B[C]): HTTPCallResult[C]
}

及其示例

type Identity[X] = X
  implicit object JsonResponseHandler extends ResponseHandler[JsValue, Identity] {
    def handle[C](response: WSResponse, parser: JsValue => C): HTTPCallResult[C] = {
      // implementation
    }
  }

在调用函数时

post[A, In, Out[_]](parser: In => Out[A])(implicit handler: ResponseHandler[In, Out]) = {
  // implementation
}

就像这样

post { resp: WSResponse =>
  resp.body == "alive"
}

它抛出编译时错误

[error] no type parameters for method post: (parser: In => Out[A])(implicit handler: ResponseHandler[In,Out]) exist so that it can be applied to arguments (WSResponse => Boolean)
[error]  --- because ---
[error] argument expression's type is not compatible with formal parameter type;
[error]  found   : WSResponse => Boolean
[error]  required: ?In => ?Out[?A]
[error]       .post { resp: WSResponse =>
[error]        ^
[error]  type mismatch;
[error]  found   : play.api.libs.ws.WSResponse => Boolean
[error]  required: In => Out[A]
[error]       .post { resp: WSResponse =>
[error]                                ^
[error]  ambiguous implicit values:
[error]  both object WSResponseHandler in object ResponseHandler of type 
[error]  ResponseHandler.WSResponseHandler.type
[error]  and object WSResponseWithErrorsHandler in object ResponseHandler of type ResponseHandler.WSResponseWithErrorsHandler.type
[error]  match expected type ResponseHandler[Any,Out]
[error]       .post { resp: WSResponse =>
[error]             ^
[error] three errors found

然而,当像这样调用时

import ResponseHandler.Identity
post { resp: WSResponse =>
  (resp.body == "alive").asInstanceOf[Identity[Boolean]]
}

它起作用了。有没有可能以某种方式帮助编译器推断类型?我试过def getIdtentity[A](a: A): Identity[A] = a.asInstanceOf[Identity[A]],但不起作用。

yr9zkbsy

yr9zkbsy1#

尝试

def post[A, In, O, Out[_]](parser: In => O)(implicit 
  handler: ResponseHandler[In, Out], 
  ev: O <:< Out[A]
) = ???

这应该有助于推断类型。
隐含的顺序为handlerev
其他选项:

ev: O =:= Out[A]
ev: Out[A] =:= O
ev: O =:= Out[A], ev1: Out[A] =:= O
ev: Out[A] <:< O
ev: O <:< Out[A], ev1: Out[A] <:< O
ev: O => Out[A]
ev: Out[A] => O
ev: O => Out[A], ev1: Out[A] => O

相关问题