0

I have a type class

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

and its instance

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

When calling function

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

like this

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

it throws a compile time error

[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 

However, when called like this

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

it works. Is it possible to somehow help compiler infer the type? I tried def getIdtentity[A](a: A): Identity[A] = a.asInstanceOf[Identity[A]], but it didn't work.

1 Answer 1

2

Try

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

This should help to infer types.

The order of implicits handler, ev is significant.

Other options:

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 
Sign up to request clarification or add additional context in comments.

9 Comments

Thank you. It works, however, now I must specify A parameter when calling the function, since the type cant be inferred from the parser method In => O. It results in Nothing.
@DavidTomecek Not sure I understand completely. I tested with code samples you provided. Could you update your question with code sample where you have to specify A?
@DavidTomecek Did you have a chance to prepare code snippet where you have to specify A?
I am so sorry, I did not respond earlier. At the end I changed the overall design of the code, that resulted in simpler implementation. Nonetheless, the problem was that the post method was supposed to return say Option[A]. The proposed solution then resulted in A being inferred as Nothing. So for instance post(f: WSResponse => Int) resulted in Option[Nothing] instead of Option[Int].
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.