Scala: Is it possible to constrain a type parameter to be non abstract?
Are any other constraints possible except view bounds, upper bounds and lower bounds for type parameters and abstract type members? In C# for example, which I'm familiar with, you have the additional generic constraints:
where T: Class //Not sure if this covered in Scala by T<: AnyRef
where T: interface
where T: struct
where U: T //naked type constraint
where T: new () //This ensures that a type parameter is non-abstract and allows one to instantiate an object of the type in the generic class.
The last one is particularly important as it allows you to construct your unknown type, although its a shame you can only proscribe a parameterless constructor.
Can =:= <:< and <%< only be used on method parameters?
In response to the comments, the immediate trigger for the question was the need for a "T: new()" restraint or some equivalent mechanism.
class ExampleClass[T <: AnyRef] {
val example: T = new T()//Won't compile as the compiler
} //doesn't know if such a constructor exists
The uses of some of the C# constraints are particular to the needs of C#. For example one restraint that you don't have in C# that people are always wanting is "T: numericType" That issue is already solved in Scala. I'm still very much boot strapping my way up the Scala language, so aside from the above, I was just trying to clarify exactly what tools are and are not available to me in this facet of Scala syntax, even though I don't know yet exactly how I might want to use them in the Scala context.
I'm not sure if this is fully related but sometimes it seems the compiler (Eclipse 2.1.0.M1 with Eclipse 3.7.2) won't let me instantiate collections of unknown element type. The following code now seems to compiles fine. So I'd like to know what the rules are:
abstract class Descrip [T <: DTypes]()
{
val hexs: MutableList[T#HexT] = new MutableList[T#HexT] //compiles fine
val sides: MutableList[T#SideT] = new MutableList[T#SideT] //compiles fine
}
The need of
new T()
is normally resolved by usingManifest
s. For example this code compiles:The drawback is that if the
T
for whichExampleClass
is instantiated doesn't have a no-arg constructor it will fail at runtime...Regarding
Numeric
,Ordering
, etc., they are type classes and are part of the standard library, not part of the language. You can build your own type classes. The case ofManifest
is special because it do have support from the language to provide the implicit object.