Reputation: 4795
I have different kinds of enumerations in this flavour
class Gender extends Enumeration {
type Gender = Value
val Male,Female = Value
}
and I would like to have a generic function that given an element of an enumeration, it puts a 1 in an array of length .maxId (if you are familiar with R, I'm trying to implement factor). But I'm not able to get the types right, my function would be something like this (wrong) code:
def toFactor[T](elem:T.Value):List[Double] = {
var array = Array.fill(T.maxId)(0.0)
array(elem.id) == 1.0
array.toList
}
How would you write this code so is generic for whatever enumeration we use?
Upvotes: 0
Views: 263
Reputation: 26576
This code should do it:
object Gender extends Enumeration {
type Gender = Value
val Male, Female = Value
}
def toFactor[E <: Enumeration, V <: E#Value](enum: E, elem: V): List[Double] = {
var array = Array.fill(enum.maxId)(0.0)
array(elem.id) = 1.0
array.toList
}
println(toFactor(Gender, Gender.Female)) // prints: List(0.0, 1.0)
You need to use E#Value
instead of E.Value
because it generally tells: any Value
of the provided Enumeration
E
. E <: Enumeration
restricts E
to be subclass of Enumeration
. You also need enum instance in order to get maxId
.
You can also simplify toFactor
method a little bit and avoid using any Array
s or id
s:
def toFactor[T <: Enumeration, V <: T#Value](enum: T, elem: V): List[Double] =
enum.values.toList map (curr => if (curr == elem) 1.0 else 0.0)
Upvotes: 1