I think I understand the new Scala 2.10 "value class" function compared to the Haskell newtype :
trait BoundedValue[+This] extends Any { this: This => def upperBound: This def lowerBound: This } class Probability @throws(classOf[IllegalArgumentException]) (v: Double) extends AnyVal with BoundedValue[Probability] { val value: Double = if ((v >= 0.0) && (v <= 1.0)) v else throw new IllegalArgumentException((v.toString) + "is not within the range [0.0, 1.0]") override val upperBound: Probability = new Probability(0.0) override val lowerBound: Probability = new Probability(1.0) // Implement probability arithmetic here; // will be represented by Double at runtime. }
I have a question: how does a value class appear in Java code that uses the Scala package in which it is declared? The class of the class is displayed as a reference class on the Java side or is it completely deleted (and thus displayed as the type it wraps)? In other words, how safe types are value classes when Java is involved at the source level?
EDIT
The above code will not compile according to the SIP-15 document (associated with Daniel's answer), since value classes are not allowed to have any initialization logic, since either v must be explicitly val or Probability must have an unbox method and an appropriate box method for this companion object, and since the value classes must have exactly one field. The correct code is:
trait BoundedValue[This <: BoundedValue[This]] extends Any { this: This => def upperBound: This def lowerBound: This } class Probability private[Probability] (value: Double) extends AnyVal with BoundedValue[Probability] { @inline override def upperBound: Probability = new Probability(0.0) @inline override def lowerBound: Probability = new Probability(1.0) @inline def unbox: Double = value // Implement probability arithmetic here; // will be represented by Double at runtime (mostly). } object Probability { @throws(classOf[IllegalArgumentException]) def box(v: Double): Probability = if ((v >= 0.0) && (v <= 1.0)) new Probability(v) else throw new IllegalArgumentException((v.toString) + "is not within the range [0.0, 1.0]") }
The question itself remains valid as it is.
java scala scala-java-interop interop newtype
Ptharien's flame
source share