简体   繁体   中英

Scala function/method parametrized return type

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM