Scala: determine method result type for use in generics
up vote
4
down vote
favorite
In a third-party library there is a series of request classes, all of which derive from some common base class, which is generic and takes response class as a parameter:
abstract class AbstractRequest[ResponseType] {
…
def execute(): ResponseType
}
class UserList {…}
class UserListRequest extends AbstractRequest[UserList] {…}
class Avatar {…}
class AvatarRequest extends AbstractRequest[Avatar] {…}
…
I want to write some generic method that takes a request instance, executes it several times in some special ways and delegates processing of the responses to a function supplied in arguments:
def specialMultiExecute(request: Req)(responseHandler: Resp => Unit): Unit = …
— to be called like:
val myRequest: UserListRequest = …
specialMultiExecute(myRequest){ userList => … }
The problem is that I need to somehow specify Req
and Resp
types in the specialMultiExecute
declaration. I tried the obvious approach:
def specialMultiExecute[Req <: AbstractRequest[Resp], Resp](request: Req)(responseHandler: Resp => Unit): Unit = …
— but Scala compiler fails to deduct generic argument types (an explicit specification like specialMultiExecute
[UserListRequest, UserList]
(myRequest){ userList => … }
is required).
In C++ in such case I could write a template function with a single template parameter Req
, while making Resp
to be determined as result type of the method Req::execute
:
template<typename Req>
void specialMultiExecute(
Req request,
std::function<void (decltype(std::declval<Req>().execute()))> responseHandler
) {…}
//i.e. we use `decltype(std::declval<Req>().execute())` instead of Resp
Is there way to write something similar is Scala?
I mean something like (in Scala-like pseudocode):
def specialMultiExecute[Req <: AbstractRequest](request: Req)(responseHandler: ResultTypeOf(Req#execute) => Unit): Unit = …
scala generics
add a comment |
up vote
4
down vote
favorite
In a third-party library there is a series of request classes, all of which derive from some common base class, which is generic and takes response class as a parameter:
abstract class AbstractRequest[ResponseType] {
…
def execute(): ResponseType
}
class UserList {…}
class UserListRequest extends AbstractRequest[UserList] {…}
class Avatar {…}
class AvatarRequest extends AbstractRequest[Avatar] {…}
…
I want to write some generic method that takes a request instance, executes it several times in some special ways and delegates processing of the responses to a function supplied in arguments:
def specialMultiExecute(request: Req)(responseHandler: Resp => Unit): Unit = …
— to be called like:
val myRequest: UserListRequest = …
specialMultiExecute(myRequest){ userList => … }
The problem is that I need to somehow specify Req
and Resp
types in the specialMultiExecute
declaration. I tried the obvious approach:
def specialMultiExecute[Req <: AbstractRequest[Resp], Resp](request: Req)(responseHandler: Resp => Unit): Unit = …
— but Scala compiler fails to deduct generic argument types (an explicit specification like specialMultiExecute
[UserListRequest, UserList]
(myRequest){ userList => … }
is required).
In C++ in such case I could write a template function with a single template parameter Req
, while making Resp
to be determined as result type of the method Req::execute
:
template<typename Req>
void specialMultiExecute(
Req request,
std::function<void (decltype(std::declval<Req>().execute()))> responseHandler
) {…}
//i.e. we use `decltype(std::declval<Req>().execute())` instead of Resp
Is there way to write something similar is Scala?
I mean something like (in Scala-like pseudocode):
def specialMultiExecute[Req <: AbstractRequest](request: Req)(responseHandler: ResultTypeOf(Req#execute) => Unit): Unit = …
scala generics
Do you need to know which sub type ofAbstractRequest
do you have, or are you fine wit only knowing whichResponseType
you have?
– Luis Miguel Mejía Suárez
Nov 21 at 20:11
@LuisMiguelMejíaSuárez, to say truth, it seems it's better forspecialMultiExecute
to know an exact subtype ofAbstractRequest
. (This may be non-obvious from the explanation above, but it's related to some unspecified dirty details on howspecialMultiExecute
internally works.) However, if I understand correctly, your first example covers this case (I'm now trying to read and understand how it works).
– Sasha
Nov 21 at 21:23
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
In a third-party library there is a series of request classes, all of which derive from some common base class, which is generic and takes response class as a parameter:
abstract class AbstractRequest[ResponseType] {
…
def execute(): ResponseType
}
class UserList {…}
class UserListRequest extends AbstractRequest[UserList] {…}
class Avatar {…}
class AvatarRequest extends AbstractRequest[Avatar] {…}
…
I want to write some generic method that takes a request instance, executes it several times in some special ways and delegates processing of the responses to a function supplied in arguments:
def specialMultiExecute(request: Req)(responseHandler: Resp => Unit): Unit = …
— to be called like:
val myRequest: UserListRequest = …
specialMultiExecute(myRequest){ userList => … }
The problem is that I need to somehow specify Req
and Resp
types in the specialMultiExecute
declaration. I tried the obvious approach:
def specialMultiExecute[Req <: AbstractRequest[Resp], Resp](request: Req)(responseHandler: Resp => Unit): Unit = …
— but Scala compiler fails to deduct generic argument types (an explicit specification like specialMultiExecute
[UserListRequest, UserList]
(myRequest){ userList => … }
is required).
In C++ in such case I could write a template function with a single template parameter Req
, while making Resp
to be determined as result type of the method Req::execute
:
template<typename Req>
void specialMultiExecute(
Req request,
std::function<void (decltype(std::declval<Req>().execute()))> responseHandler
) {…}
//i.e. we use `decltype(std::declval<Req>().execute())` instead of Resp
Is there way to write something similar is Scala?
I mean something like (in Scala-like pseudocode):
def specialMultiExecute[Req <: AbstractRequest](request: Req)(responseHandler: ResultTypeOf(Req#execute) => Unit): Unit = …
scala generics
In a third-party library there is a series of request classes, all of which derive from some common base class, which is generic and takes response class as a parameter:
abstract class AbstractRequest[ResponseType] {
…
def execute(): ResponseType
}
class UserList {…}
class UserListRequest extends AbstractRequest[UserList] {…}
class Avatar {…}
class AvatarRequest extends AbstractRequest[Avatar] {…}
…
I want to write some generic method that takes a request instance, executes it several times in some special ways and delegates processing of the responses to a function supplied in arguments:
def specialMultiExecute(request: Req)(responseHandler: Resp => Unit): Unit = …
— to be called like:
val myRequest: UserListRequest = …
specialMultiExecute(myRequest){ userList => … }
The problem is that I need to somehow specify Req
and Resp
types in the specialMultiExecute
declaration. I tried the obvious approach:
def specialMultiExecute[Req <: AbstractRequest[Resp], Resp](request: Req)(responseHandler: Resp => Unit): Unit = …
— but Scala compiler fails to deduct generic argument types (an explicit specification like specialMultiExecute
[UserListRequest, UserList]
(myRequest){ userList => … }
is required).
In C++ in such case I could write a template function with a single template parameter Req
, while making Resp
to be determined as result type of the method Req::execute
:
template<typename Req>
void specialMultiExecute(
Req request,
std::function<void (decltype(std::declval<Req>().execute()))> responseHandler
) {…}
//i.e. we use `decltype(std::declval<Req>().execute())` instead of Resp
Is there way to write something similar is Scala?
I mean something like (in Scala-like pseudocode):
def specialMultiExecute[Req <: AbstractRequest](request: Req)(responseHandler: ResultTypeOf(Req#execute) => Unit): Unit = …
scala generics
scala generics
asked Nov 21 at 19:57
Sasha
1,5301528
1,5301528
Do you need to know which sub type ofAbstractRequest
do you have, or are you fine wit only knowing whichResponseType
you have?
– Luis Miguel Mejía Suárez
Nov 21 at 20:11
@LuisMiguelMejíaSuárez, to say truth, it seems it's better forspecialMultiExecute
to know an exact subtype ofAbstractRequest
. (This may be non-obvious from the explanation above, but it's related to some unspecified dirty details on howspecialMultiExecute
internally works.) However, if I understand correctly, your first example covers this case (I'm now trying to read and understand how it works).
– Sasha
Nov 21 at 21:23
add a comment |
Do you need to know which sub type ofAbstractRequest
do you have, or are you fine wit only knowing whichResponseType
you have?
– Luis Miguel Mejía Suárez
Nov 21 at 20:11
@LuisMiguelMejíaSuárez, to say truth, it seems it's better forspecialMultiExecute
to know an exact subtype ofAbstractRequest
. (This may be non-obvious from the explanation above, but it's related to some unspecified dirty details on howspecialMultiExecute
internally works.) However, if I understand correctly, your first example covers this case (I'm now trying to read and understand how it works).
– Sasha
Nov 21 at 21:23
Do you need to know which sub type of
AbstractRequest
do you have, or are you fine wit only knowing which ResponseType
you have?– Luis Miguel Mejía Suárez
Nov 21 at 20:11
Do you need to know which sub type of
AbstractRequest
do you have, or are you fine wit only knowing which ResponseType
you have?– Luis Miguel Mejía Suárez
Nov 21 at 20:11
@LuisMiguelMejíaSuárez, to say truth, it seems it's better for
specialMultiExecute
to know an exact subtype of AbstractRequest
. (This may be non-obvious from the explanation above, but it's related to some unspecified dirty details on how specialMultiExecute
internally works.) However, if I understand correctly, your first example covers this case (I'm now trying to read and understand how it works).– Sasha
Nov 21 at 21:23
@LuisMiguelMejíaSuárez, to say truth, it seems it's better for
specialMultiExecute
to know an exact subtype of AbstractRequest
. (This may be non-obvious from the explanation above, but it's related to some unspecified dirty details on how specialMultiExecute
internally works.) However, if I understand correctly, your first example covers this case (I'm now trying to read and understand how it works).– Sasha
Nov 21 at 21:23
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
It is a limitation of the type inference mechanism.
The simplest way to solve it is to use an implicit evidence that Req
is a subtype of AbstractRequest[ResponseType]
.
Here is an example.
import scala.language.implicitConversions
import scala.reflect.runtime.universe.TypeTag
abstract class AbstractRequest[ResponseType] {
def execute(): ResponseType
}
final case class User(id: Int, name: String)
final case class House(id: Int, price: Int)
class UserListRequest extends AbstractRequest[List[User]] {
override def execute(): List[User] = List(User(id = 3, name = "Sasha"))
override def toString: String = "UserListRequest"
}
final class RequestWrapper[Req, Resp](val request: Req) extends AnyVal {
type ResponseType = Resp
}
implicit def request2wrapper[Req, Resp](request: Req)(implicit ev: Req <:< AbstractRequest[Resp]): RequestWrapper[Req, Resp] =
new RequestWrapper(request)
def specialMultiExecute[Req, Resp](wrapper: RequestWrapper[Req, Resp])
(responseHandler: wrapper.ResponseType => Unit)
(implicit ev: Req <:< AbstractRequest[Resp], TTReq: TypeTag[Req], TTResp: TypeTag[Resp]): Unit = {
val request: Req = wrapper.request
val executionResult: Resp = request.execute()
responseHandler(executionResult)
println(TTReq)
println(TTResp)
println(request)
}
specialMultiExecute(new UserListRequest())(println)
// List(User(3,Sasha))
// TypeTag[UserListRequest]
// TypeTag[List[User]]
// UserListRequest
Reference for
<:<
.
Reference for "Dependent types".
Edit
Te above code example was modified to allow identification of the concrete Request
and Response
types being used.
Although your answer doesn't answer my question directly (i.e. whether it is possible to get method result type in a way usable for generics), I got plenty other useful information from it. Therefore I accept it. (Additionally I found a way to make dirty internal details ofspecialMultiExecute
to work without knowing exactReq
type.)
– Sasha
Nov 22 at 12:37
Hi @Sasha, I'm glad it help you. I think the first code snippet provides you with all the information you need. (e.g. The exact type ofReq
&Resp
), or am I missing something ?
– Luis Miguel Mejía Suárez
Nov 22 at 12:59
In the first snippetReq[ResponseType]
isAbstractRequest[List[User]]
, notUserListRequest
. We can check that, for example, byprintln(scala.reflect.runtime.universe.typeOf[Req[ResponseType]])
.
– Sasha
Nov 22 at 13:19
1
@Sasha ah, you're right. The reason is thatUserListRequest
doesn't match the signature typeReq[_]
since it doesn't takes any type argument - my bad, sorry. I think I can fix it, and will update the answer once it is done.
– Luis Miguel Mejía Suárez
Nov 22 at 15:48
Thanks. Actually, now the type of response still needs to be specified during a call, although it has moved from [UserListRequest, List[User]] tol: List[User]
(but yeah, now we need to specify onlyResp
, not bothReq
andResp
). Anyway, as said before, I had found a way to makespecialMultiExecute
to work without knowing exactReq
type, so now it's just for satisfying my thirst for research.
– Sasha
Nov 22 at 16:48
|
show 1 more comment
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
It is a limitation of the type inference mechanism.
The simplest way to solve it is to use an implicit evidence that Req
is a subtype of AbstractRequest[ResponseType]
.
Here is an example.
import scala.language.implicitConversions
import scala.reflect.runtime.universe.TypeTag
abstract class AbstractRequest[ResponseType] {
def execute(): ResponseType
}
final case class User(id: Int, name: String)
final case class House(id: Int, price: Int)
class UserListRequest extends AbstractRequest[List[User]] {
override def execute(): List[User] = List(User(id = 3, name = "Sasha"))
override def toString: String = "UserListRequest"
}
final class RequestWrapper[Req, Resp](val request: Req) extends AnyVal {
type ResponseType = Resp
}
implicit def request2wrapper[Req, Resp](request: Req)(implicit ev: Req <:< AbstractRequest[Resp]): RequestWrapper[Req, Resp] =
new RequestWrapper(request)
def specialMultiExecute[Req, Resp](wrapper: RequestWrapper[Req, Resp])
(responseHandler: wrapper.ResponseType => Unit)
(implicit ev: Req <:< AbstractRequest[Resp], TTReq: TypeTag[Req], TTResp: TypeTag[Resp]): Unit = {
val request: Req = wrapper.request
val executionResult: Resp = request.execute()
responseHandler(executionResult)
println(TTReq)
println(TTResp)
println(request)
}
specialMultiExecute(new UserListRequest())(println)
// List(User(3,Sasha))
// TypeTag[UserListRequest]
// TypeTag[List[User]]
// UserListRequest
Reference for
<:<
.
Reference for "Dependent types".
Edit
Te above code example was modified to allow identification of the concrete Request
and Response
types being used.
Although your answer doesn't answer my question directly (i.e. whether it is possible to get method result type in a way usable for generics), I got plenty other useful information from it. Therefore I accept it. (Additionally I found a way to make dirty internal details ofspecialMultiExecute
to work without knowing exactReq
type.)
– Sasha
Nov 22 at 12:37
Hi @Sasha, I'm glad it help you. I think the first code snippet provides you with all the information you need. (e.g. The exact type ofReq
&Resp
), or am I missing something ?
– Luis Miguel Mejía Suárez
Nov 22 at 12:59
In the first snippetReq[ResponseType]
isAbstractRequest[List[User]]
, notUserListRequest
. We can check that, for example, byprintln(scala.reflect.runtime.universe.typeOf[Req[ResponseType]])
.
– Sasha
Nov 22 at 13:19
1
@Sasha ah, you're right. The reason is thatUserListRequest
doesn't match the signature typeReq[_]
since it doesn't takes any type argument - my bad, sorry. I think I can fix it, and will update the answer once it is done.
– Luis Miguel Mejía Suárez
Nov 22 at 15:48
Thanks. Actually, now the type of response still needs to be specified during a call, although it has moved from [UserListRequest, List[User]] tol: List[User]
(but yeah, now we need to specify onlyResp
, not bothReq
andResp
). Anyway, as said before, I had found a way to makespecialMultiExecute
to work without knowing exactReq
type, so now it's just for satisfying my thirst for research.
– Sasha
Nov 22 at 16:48
|
show 1 more comment
up vote
3
down vote
accepted
It is a limitation of the type inference mechanism.
The simplest way to solve it is to use an implicit evidence that Req
is a subtype of AbstractRequest[ResponseType]
.
Here is an example.
import scala.language.implicitConversions
import scala.reflect.runtime.universe.TypeTag
abstract class AbstractRequest[ResponseType] {
def execute(): ResponseType
}
final case class User(id: Int, name: String)
final case class House(id: Int, price: Int)
class UserListRequest extends AbstractRequest[List[User]] {
override def execute(): List[User] = List(User(id = 3, name = "Sasha"))
override def toString: String = "UserListRequest"
}
final class RequestWrapper[Req, Resp](val request: Req) extends AnyVal {
type ResponseType = Resp
}
implicit def request2wrapper[Req, Resp](request: Req)(implicit ev: Req <:< AbstractRequest[Resp]): RequestWrapper[Req, Resp] =
new RequestWrapper(request)
def specialMultiExecute[Req, Resp](wrapper: RequestWrapper[Req, Resp])
(responseHandler: wrapper.ResponseType => Unit)
(implicit ev: Req <:< AbstractRequest[Resp], TTReq: TypeTag[Req], TTResp: TypeTag[Resp]): Unit = {
val request: Req = wrapper.request
val executionResult: Resp = request.execute()
responseHandler(executionResult)
println(TTReq)
println(TTResp)
println(request)
}
specialMultiExecute(new UserListRequest())(println)
// List(User(3,Sasha))
// TypeTag[UserListRequest]
// TypeTag[List[User]]
// UserListRequest
Reference for
<:<
.
Reference for "Dependent types".
Edit
Te above code example was modified to allow identification of the concrete Request
and Response
types being used.
Although your answer doesn't answer my question directly (i.e. whether it is possible to get method result type in a way usable for generics), I got plenty other useful information from it. Therefore I accept it. (Additionally I found a way to make dirty internal details ofspecialMultiExecute
to work without knowing exactReq
type.)
– Sasha
Nov 22 at 12:37
Hi @Sasha, I'm glad it help you. I think the first code snippet provides you with all the information you need. (e.g. The exact type ofReq
&Resp
), or am I missing something ?
– Luis Miguel Mejía Suárez
Nov 22 at 12:59
In the first snippetReq[ResponseType]
isAbstractRequest[List[User]]
, notUserListRequest
. We can check that, for example, byprintln(scala.reflect.runtime.universe.typeOf[Req[ResponseType]])
.
– Sasha
Nov 22 at 13:19
1
@Sasha ah, you're right. The reason is thatUserListRequest
doesn't match the signature typeReq[_]
since it doesn't takes any type argument - my bad, sorry. I think I can fix it, and will update the answer once it is done.
– Luis Miguel Mejía Suárez
Nov 22 at 15:48
Thanks. Actually, now the type of response still needs to be specified during a call, although it has moved from [UserListRequest, List[User]] tol: List[User]
(but yeah, now we need to specify onlyResp
, not bothReq
andResp
). Anyway, as said before, I had found a way to makespecialMultiExecute
to work without knowing exactReq
type, so now it's just for satisfying my thirst for research.
– Sasha
Nov 22 at 16:48
|
show 1 more comment
up vote
3
down vote
accepted
up vote
3
down vote
accepted
It is a limitation of the type inference mechanism.
The simplest way to solve it is to use an implicit evidence that Req
is a subtype of AbstractRequest[ResponseType]
.
Here is an example.
import scala.language.implicitConversions
import scala.reflect.runtime.universe.TypeTag
abstract class AbstractRequest[ResponseType] {
def execute(): ResponseType
}
final case class User(id: Int, name: String)
final case class House(id: Int, price: Int)
class UserListRequest extends AbstractRequest[List[User]] {
override def execute(): List[User] = List(User(id = 3, name = "Sasha"))
override def toString: String = "UserListRequest"
}
final class RequestWrapper[Req, Resp](val request: Req) extends AnyVal {
type ResponseType = Resp
}
implicit def request2wrapper[Req, Resp](request: Req)(implicit ev: Req <:< AbstractRequest[Resp]): RequestWrapper[Req, Resp] =
new RequestWrapper(request)
def specialMultiExecute[Req, Resp](wrapper: RequestWrapper[Req, Resp])
(responseHandler: wrapper.ResponseType => Unit)
(implicit ev: Req <:< AbstractRequest[Resp], TTReq: TypeTag[Req], TTResp: TypeTag[Resp]): Unit = {
val request: Req = wrapper.request
val executionResult: Resp = request.execute()
responseHandler(executionResult)
println(TTReq)
println(TTResp)
println(request)
}
specialMultiExecute(new UserListRequest())(println)
// List(User(3,Sasha))
// TypeTag[UserListRequest]
// TypeTag[List[User]]
// UserListRequest
Reference for
<:<
.
Reference for "Dependent types".
Edit
Te above code example was modified to allow identification of the concrete Request
and Response
types being used.
It is a limitation of the type inference mechanism.
The simplest way to solve it is to use an implicit evidence that Req
is a subtype of AbstractRequest[ResponseType]
.
Here is an example.
import scala.language.implicitConversions
import scala.reflect.runtime.universe.TypeTag
abstract class AbstractRequest[ResponseType] {
def execute(): ResponseType
}
final case class User(id: Int, name: String)
final case class House(id: Int, price: Int)
class UserListRequest extends AbstractRequest[List[User]] {
override def execute(): List[User] = List(User(id = 3, name = "Sasha"))
override def toString: String = "UserListRequest"
}
final class RequestWrapper[Req, Resp](val request: Req) extends AnyVal {
type ResponseType = Resp
}
implicit def request2wrapper[Req, Resp](request: Req)(implicit ev: Req <:< AbstractRequest[Resp]): RequestWrapper[Req, Resp] =
new RequestWrapper(request)
def specialMultiExecute[Req, Resp](wrapper: RequestWrapper[Req, Resp])
(responseHandler: wrapper.ResponseType => Unit)
(implicit ev: Req <:< AbstractRequest[Resp], TTReq: TypeTag[Req], TTResp: TypeTag[Resp]): Unit = {
val request: Req = wrapper.request
val executionResult: Resp = request.execute()
responseHandler(executionResult)
println(TTReq)
println(TTResp)
println(request)
}
specialMultiExecute(new UserListRequest())(println)
// List(User(3,Sasha))
// TypeTag[UserListRequest]
// TypeTag[List[User]]
// UserListRequest
Reference for
<:<
.
Reference for "Dependent types".
Edit
Te above code example was modified to allow identification of the concrete Request
and Response
types being used.
edited Nov 23 at 14:18
answered Nov 21 at 20:26
Luis Miguel Mejía Suárez
1,467719
1,467719
Although your answer doesn't answer my question directly (i.e. whether it is possible to get method result type in a way usable for generics), I got plenty other useful information from it. Therefore I accept it. (Additionally I found a way to make dirty internal details ofspecialMultiExecute
to work without knowing exactReq
type.)
– Sasha
Nov 22 at 12:37
Hi @Sasha, I'm glad it help you. I think the first code snippet provides you with all the information you need. (e.g. The exact type ofReq
&Resp
), or am I missing something ?
– Luis Miguel Mejía Suárez
Nov 22 at 12:59
In the first snippetReq[ResponseType]
isAbstractRequest[List[User]]
, notUserListRequest
. We can check that, for example, byprintln(scala.reflect.runtime.universe.typeOf[Req[ResponseType]])
.
– Sasha
Nov 22 at 13:19
1
@Sasha ah, you're right. The reason is thatUserListRequest
doesn't match the signature typeReq[_]
since it doesn't takes any type argument - my bad, sorry. I think I can fix it, and will update the answer once it is done.
– Luis Miguel Mejía Suárez
Nov 22 at 15:48
Thanks. Actually, now the type of response still needs to be specified during a call, although it has moved from [UserListRequest, List[User]] tol: List[User]
(but yeah, now we need to specify onlyResp
, not bothReq
andResp
). Anyway, as said before, I had found a way to makespecialMultiExecute
to work without knowing exactReq
type, so now it's just for satisfying my thirst for research.
– Sasha
Nov 22 at 16:48
|
show 1 more comment
Although your answer doesn't answer my question directly (i.e. whether it is possible to get method result type in a way usable for generics), I got plenty other useful information from it. Therefore I accept it. (Additionally I found a way to make dirty internal details ofspecialMultiExecute
to work without knowing exactReq
type.)
– Sasha
Nov 22 at 12:37
Hi @Sasha, I'm glad it help you. I think the first code snippet provides you with all the information you need. (e.g. The exact type ofReq
&Resp
), or am I missing something ?
– Luis Miguel Mejía Suárez
Nov 22 at 12:59
In the first snippetReq[ResponseType]
isAbstractRequest[List[User]]
, notUserListRequest
. We can check that, for example, byprintln(scala.reflect.runtime.universe.typeOf[Req[ResponseType]])
.
– Sasha
Nov 22 at 13:19
1
@Sasha ah, you're right. The reason is thatUserListRequest
doesn't match the signature typeReq[_]
since it doesn't takes any type argument - my bad, sorry. I think I can fix it, and will update the answer once it is done.
– Luis Miguel Mejía Suárez
Nov 22 at 15:48
Thanks. Actually, now the type of response still needs to be specified during a call, although it has moved from [UserListRequest, List[User]] tol: List[User]
(but yeah, now we need to specify onlyResp
, not bothReq
andResp
). Anyway, as said before, I had found a way to makespecialMultiExecute
to work without knowing exactReq
type, so now it's just for satisfying my thirst for research.
– Sasha
Nov 22 at 16:48
Although your answer doesn't answer my question directly (i.e. whether it is possible to get method result type in a way usable for generics), I got plenty other useful information from it. Therefore I accept it. (Additionally I found a way to make dirty internal details of
specialMultiExecute
to work without knowing exact Req
type.)– Sasha
Nov 22 at 12:37
Although your answer doesn't answer my question directly (i.e. whether it is possible to get method result type in a way usable for generics), I got plenty other useful information from it. Therefore I accept it. (Additionally I found a way to make dirty internal details of
specialMultiExecute
to work without knowing exact Req
type.)– Sasha
Nov 22 at 12:37
Hi @Sasha, I'm glad it help you. I think the first code snippet provides you with all the information you need. (e.g. The exact type of
Req
& Resp
), or am I missing something ?– Luis Miguel Mejía Suárez
Nov 22 at 12:59
Hi @Sasha, I'm glad it help you. I think the first code snippet provides you with all the information you need. (e.g. The exact type of
Req
& Resp
), or am I missing something ?– Luis Miguel Mejía Suárez
Nov 22 at 12:59
In the first snippet
Req[ResponseType]
is AbstractRequest[List[User]]
, not UserListRequest
. We can check that, for example, by println(scala.reflect.runtime.universe.typeOf[Req[ResponseType]])
.– Sasha
Nov 22 at 13:19
In the first snippet
Req[ResponseType]
is AbstractRequest[List[User]]
, not UserListRequest
. We can check that, for example, by println(scala.reflect.runtime.universe.typeOf[Req[ResponseType]])
.– Sasha
Nov 22 at 13:19
1
1
@Sasha ah, you're right. The reason is that
UserListRequest
doesn't match the signature type Req[_]
since it doesn't takes any type argument - my bad, sorry. I think I can fix it, and will update the answer once it is done.– Luis Miguel Mejía Suárez
Nov 22 at 15:48
@Sasha ah, you're right. The reason is that
UserListRequest
doesn't match the signature type Req[_]
since it doesn't takes any type argument - my bad, sorry. I think I can fix it, and will update the answer once it is done.– Luis Miguel Mejía Suárez
Nov 22 at 15:48
Thanks. Actually, now the type of response still needs to be specified during a call, although it has moved from [UserListRequest, List[User]] to
l: List[User]
(but yeah, now we need to specify only Resp
, not both Req
and Resp
). Anyway, as said before, I had found a way to make specialMultiExecute
to work without knowing exact Req
type, so now it's just for satisfying my thirst for research.– Sasha
Nov 22 at 16:48
Thanks. Actually, now the type of response still needs to be specified during a call, although it has moved from [UserListRequest, List[User]] to
l: List[User]
(but yeah, now we need to specify only Resp
, not both Req
and Resp
). Anyway, as said before, I had found a way to make specialMultiExecute
to work without knowing exact Req
type, so now it's just for satisfying my thirst for research.– Sasha
Nov 22 at 16:48
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419634%2fscala-determine-method-result-type-for-use-in-generics%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Do you need to know which sub type of
AbstractRequest
do you have, or are you fine wit only knowing whichResponseType
you have?– Luis Miguel Mejía Suárez
Nov 21 at 20:11
@LuisMiguelMejíaSuárez, to say truth, it seems it's better for
specialMultiExecute
to know an exact subtype ofAbstractRequest
. (This may be non-obvious from the explanation above, but it's related to some unspecified dirty details on howspecialMultiExecute
internally works.) However, if I understand correctly, your first example covers this case (I'm now trying to read and understand how it works).– Sasha
Nov 21 at 21:23