I have just come up with something that I don't understand. I'm trying to return a parametrized type from a method, the code is the following (working example):
trait Expression
case class ExpImp1() extends Expression
case class ExpImp2() extends Expression
object Main {
private def testParametrizedTypes[T](): T = {
ExpImp1()
}
private def testWrappedParametrizedTypes[T <: Expression](): Option[T] = {
Some(new ExpImp1())
}
def main(args: Array[String]) {
}
}
but when I compile this code, the compiler says (the IDE warns me about the same error in both functions):
Error:(10, 12) type mismatch;
found : ExpImp1
required: T
ExpImp1()
^
I think that the code showed previously should work. In the first method I'm returning a type T and T has no constraint. The compiler error also occurs in the second method, but the parametrized type conforms to the returned object type too.
Also, I wrote a code a few weeks ago that looked like that that compiled with no problems (this is not a working example as this code is part of a Play Framework project):
class CanBeAuthenticatedRequest[A](val request: Request[A]) extends WrappedRequest[A](request)
class UnauthenticatedRequest[A](override val request: Request[A]) extends CanBeAuthenticatedRequest(request)
class AuthenticatedRequest[A](val user: String, override val request: Request[A]) extends CanBeAuthenticatedRequest[A](request)
object CanBeAuthenticatedAction extends ActionBuilder[CanBeAuthenticatedRequest] {
def invokeBlock[A]...
}
object Fold {
private def partialFunctionBuilder[T](authenticated: (AuthenticatedRequest[_]) => T)
(unauthenticated: (UnauthenticatedRequest[_]) => T):
PartialFunction[CanBeAuthenticatedRequest[_], T] = {
case ar: AuthenticatedRequest[_] => authenticated(ar)
case ur: UnauthenticatedRequest[_] => unauthenticated(ur)
}
def apply[T](request: CanBeAuthenticatedRequest[_])
(authenticated: (AuthenticatedRequest[_]) => T)
(unauthenticated: (UnauthenticatedRequest[_]) => T): T = {
partialFunctionBuilder(authenticated)(unauthenticated)(request)
}
}
}
As you can see, I successfully defined the function "partialFunctionBuilder" and I'm using it.
"partialFunctionBuilder" follows the same pattern, returning a type that is parametrized with "T". I don't see what's the difference between the code I showed first and the Play Framework code. Removing "<: Expression" from the "testWrappedParametrizedTypes" keeps giving me the same error.
When a function has a type parameter with some constraints, it should be possible to call it with any parameter, satisfying those constraints. So given the definitions it should be possible to call testParametrizedTypes[String]()
or testWrappedParametrizedTypes[ExpImpl2]()
. But because in both cases you return a fixed type ExpImpl1
, or Option[ExpImpl1]
, there is a type mismatch.
And in the Play example it is possible to call partialFunctionBuilder
, with any type T
, if you pass it the correct functions, which return that type T
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.