Scala: using type parameters or abstract types as type constraints

Suppose I have:

class Bounded[A] { type apply[C <: A] = C } 

This compiles:

 implicitly[Bounded[Any]#apply[String] =:= String] 

This fails:

 type Str = Bounded[Any]#apply[String] 

... from:

 [error] /home/grant/Workspace/scunits/test/src/main/scala/Box.scala:37: type arguments[String] do not conform to type apply type parameter bounds [C <: A] [error] type Str = Bounded[Any]#apply[String] [error] ^ 

I tried using abstract types instead of type parameters, with the same result. The only thing I found was to instantiate the type. This compiles:

 val boundedAny = new Bounded[Any] type Str2 = boundedAny.apply[String] 

Unfortunately, I work with phantom types that do not have run-time instances, often for performance reasons.

Why is Scala creating a compilation error here? Is there any more efficient work?

Thanks for any help.

Update: In addition to the workaround below, I need a way to override types with abstract type constraints. I did it like this:

 object Test { class AbstractBounded[A] { type apply[C <: A] <: A class Workaround[C <: A] { type go = apply[C] } } class Bounded[A] extends AbstractBounded[A] { type apply[C <: A] = C } type Str = Bounded[Any]#Workaround[String]#go } 
+8
types scala
source share
1 answer

What about:

 scala> class Bounded[A] { class i[C <: A]{ type apply = C}} defined class Bounded scala> type TTT = Bounded[Any]#i[String]#apply defined type alias TTT scala> implicitly[TTT =:= String] res4: =:=[TTT,String] = <function1> 

Scala forgot to look for a generic (or other "abstract" type) before binding a parameter to an alias type. Given that =: = works great - it seems like a mistake to me. Perhaps implications are resolved at another compilation level or immediately before this check.

+1
source share

All Articles