Reputation: 11512
I'd like to use an Enumeration as a type parameter by the compiler is giving me grief.
object VehicleClass extends Enumeration {
type VehicleClass = Value
val Land, Air, Sea = Value
}
import VehicleClass._
trait Vehicle[K <: VehicleClass] { val kind: K }
case class Car(passengers: Int) extends Vehicle[Land] { val kind: Land }
Compiler complains:
[error] /Users/me/test/scala/co.blocke.scalajack/json/test.misc/Greg.scala:18: not found: type Land
[error] case class Car(passengers: Int) extends Vehicle[Land] { val kind: Land }
[error] ^
[error] /Users/me/test/scala/co.blocke.scalajack/json/test.misc/Greg.scala:18: not found: type Land
[error] case class Car(passengers: Int) extends Vehicle[Land] { val kind: Land }
[error] ^
How can this be done?
Upvotes: 2
Views: 825
Reputation: 10928
Alexey has provided the correct answer for using scala.Enumeration
I would address this problem using an ADT instead of enumerations which I regard as deprecated. (See http://underscore.io/blog/posts/2014/09/03/enumerations.html)
Here is the solution using ADTs
// Using an abstract class makes accessing things in VehicleClass companion
// object nicer
sealed abstract class VehicleClass
case object Land extends VehicleClass
case object Air extends VehicleClass
case object Sea extends VehicleClass
trait Vehicle[K <: VehicleClass] { val kind: K }
case class Car(passengers: Int) extends Vehicle[Land.type] { val kind = Land }
I would simplify this code somewhat, as generally do not see the requirement to make the trait Vehicle
generic. What extra safety does this add to your code? I would generally simplify the trait to
trait Vehicle { val kind: VehicleClass }
(The only reason I can see to make Vehicle
generic would be to define type class instances for Vehicle[Land]
instead of for all of the types of Vehicle[Land]
, but then Vehicle
would probably need more members.)
Upvotes: 1
Reputation: 170713
You can write
case class Car(passengers: Int) extends Vehicle[Land.type] {
val kind: Land.type = Land
}
Land.type
is the singleton type of Land
, i.e. the type whose only value is Land
(not including null
).
Upvotes: 2