简体   繁体   中英

Scala method type parameter can not accept existential type in forSome form

In Scala, an existential type has the following two forms:

 // placeholder syntax
 List[_]
 // forSome
 List[T forSome {type T}]

However, seems that the second form can not appear in the method type parameter position(at least in the way like I write below).

  // placeholder syntax is Okay
  scala> def foo[List[_]](x: List[_]) = x
  foo: [List[_]](x: List[_])List[_]

  scala> def foo[List[t forSome {type t}]](x: List[_]) = x
  <console>:1: error: ']' expected but 'forSome' found.
  def foo[List[T forSome {type T}]](x: List[_]) = x
                  ^

  // being as upper bound is also Okay
  scala> def foo[A <: List[T forSome { type T }]](x: A) = x
  foo: [A <: List[T forSome { type T }]](x: A)A

  // type alias is a possible way but that is not what I want
  scala> type BB = List[T forSome {type T}]
  defined type alias BB

  scala> def foo[BB](x: List[_]) = x
  foo: [BB](x: List[_])List[Any]

I have tried for a while but been unable to find the right way to get the second compiled successfully. So is it just some restrictions about method type parameter, or am i missing something here.

The confusion is that the underscore ( _ ) in foo does not denote an existential type.

Let's see what the following actually means:

def foo[List[_]](x: List[_]) = x

List here is a higher kinded type parameter (and by the way does not refer to scala's built-in List type -- aka scala.collection.immutable ). This type parameter itself has a single type parameter, denoted by the underscore ( _ ).

Now that it's clear that List[_] is not an existential here, it follows that forSome has no business going there.

However, you can use forSome in the type of x . The following is equivalent to your original definition of foo :

def foo[List[_]](x: List[T] forSome { type T }) = x

Then again, this is probably still not what you'd want, seeing as List is still a type parameter and not scala.collection.immutable . What you'd probably want is:

def foo(x: List[T] forSome { type T }) = x

which is the same as:

def foo(x: List[_]) = x

Hinted by Régis Jean-Gilles's "List here is a higher-kinded type parameter (and by the way does not refer to Scala's built-in List type -- aka scala.collection.immutable)", I had a re-check on the definition of existential type and finally figured out the problem in my case, just write it here as complement for Régis Jean-Gilles's answer.

Existential types are a means of constructing types where portions of the type signature are existential, where existential means that although some real type meets that portion of a type signature, we don't care about the specific type. Existential types were introduced into Scala as a means to interoperate with Java's generic types , such as Iterator<?> or Iterator<? extends Component> Iterator<?> or Iterator<? extends Component> (Quote from <<Scala In Depth>> ).

Real type could be type from the library(like the scala.collection.immutable.List), or the self-defined type like type alias BB in my case. Anyway, Scala compiler has to guarantee that part of the existential type is also known .

The problem in my case is that

 // List is type parameter which accepts another type as parameter
 def foo[List[_]](x: List[_]) = x
 // List may be misleading here, just change it to another name
 def foo[TT[_]](x: TT[_]) = x

Scala compiler only knows that TT is higher-kinded type parameter, apparently no real type exists here . So in this case, TT[_] is not a existential type therefore forSome form can not be used in the type parameter position. And the following cases are valid.

// we define a higher-kined type HKT, so HKT is a real type 
// when Scala compiler checks the method parameter part
// HKT can be defined as existential type
def foo[HKT[_]](x: HKT[T forSome { type T }]) = x
def foo[HKT[_]](x: HKT[T] forSome { type T }) = x

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