Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make a class generic for all Numeric Types?

Tags:

I am trying to create a Vector class that is generic for all numeric types. my original attempt was to write a class for all Types like this:

class Vector3f(val x:Float, val y:Float, val z:Float) 

since scala supports the specialised annotation I could use this to generate me these classes for all numeric types

class Vector3[A <: What?](val x:A,val y:A, val z:A) 

but everything I found as a super type for numbers was AnyVal, but AnyVal does not support + - * /. So what is the right way to do this, but without sacrificing the performance of unboxed number types?

like image 561
Arne Avatar asked Jan 20 '11 22:01

Arne


People also ask

How do you create a generic class?

To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class. As you can see, all occurrences of Object are replaced by T.

Can classes be generic?

Java Generic Classes and SubtypingWe can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses.

Which is the correct way to create an object of generic class?

Like C++, we use <> to specify parameter types in generic class creation. To create objects of a generic class, we use the following syntax. Note: In Parameter type we can not use primitives like 'int','char' or 'double'.

How do you define a generic class in Java?

A Generic class simply means that the items or functions in that class can be generalized with the parameter(example T) to specify that we can add any type as a parameter in place of T like Integer, Character, String, Double or any other user-defined type.


Video Answer


1 Answers

You can't. Not right now. Maybe when, and if, Numeric gets specialized.

Say you get the simplest parameterized class possible:

class Vector3[@specialized T](val x: T, val y: T, val z: T)(implicit num: Numeric[T]) {     def +(other: Vector3[T]) = new Vector3(num.plus(x, other.x), num.plus(y, other.y), num.plus(z, other.z)) } 

The method + will compile into something roughly like this:

override <specialized> def +$mcD$sp(other: Vector3): Vector3 = new Vector3$mcD$sp(   scala.Double.unbox(     Vector3$mcD$sp.this.Vector3$$num.plus(       scala.Double.box(Vector3$mcD$sp.this.x()),        scala.Double.box(other.x$mcD$sp()))),   scala.Double.unbox(     Vector3$mcD$sp.this.Vector3$$num.plus(       scala.Double.box(Vector3$mcD$sp.this.y()),       scala.Double.box(other.y$mcD$sp()))),   scala.Double.unbox(     Vector3$mcD$sp.this.Vector3$$num.plus(       scala.Double.box(Vector3$mcD$sp.this.z()),        scala.Double.box(other.z$mcD$sp()))),    Vector3$mcD$sp.this.Vector3$$num); 

That's scalac -optimize -Xprint:jvm output. Now there are even subclasses for each specialized type, so that you can initialize a Vector3 without boxing, but as long as Numeric is not specialized, you can't go further.

Well... you can write your own Numeric and specialize that, but, at that point, I'm not sure what you are gaining by making the class parameterized in first place.

like image 195
Daniel C. Sobral Avatar answered Sep 28 '22 09:09

Daniel C. Sobral