Is it possible in Scala to create something like type aliases that can be used to enforce certain conditions? Yes, I know, this sounds somewhat strange, but let me illustrate what I mean.
Let's say we want to have only positive Integers of the type java.lang.Integer
. This class does of course allow also negative integers, so it wouldn't be sufficient to use this type in cases where only positive integers are allowed. My vague idea is to have something like an "enforced type alias".
// vague idea
object PositiveInteger {
import java.lang.{Integer, Math}
type PositiveInteger = Integer // something like this, but enforced
def apply(value: Int) = new PositiveInteger(Math.abs(value))
}
And then I want do be able to define parameters and values of the type PositiveInteger
and relying on the fact that they are positive:
def calculate(value: PositiveInteger) = ...
I want to avoid wrapping the class within another (value) class, because I would need to repeat all the methods or always access a field holding the wrapped object from the outside.
As far as I know, that wouldn't be possible in Scala, but maybe you know a way to achieve this. Do you?
You can use this technique from scalaz, to add a tag on a type (http://eed3si9n.com/learning-scalaz/Tagged+type.html)
// Entering paste mode (ctrl-D to finish)
type Tagged[U] = {type Tag = U }
type @@[T, U] = T with Tagged[U]
object Tag {
@inline def apply[T, U](t : T) : T @@ U = t.asInstanceOf[T @@ U]
}
sealed trait PositiveInt
object PositiveInt {
def apply(i : Int) : Int @@ PositiveInt = Tag(Math.abs(i))
def unapply(p : Int @@ PositiveInt) : Option[Int] = Some(p)
}
// Exiting paste mode, now interpreting.
And the result is :
defined type alias Tagged
defined type alias $at$at
defined object Tag
defined trait PositiveInt
defined object PositiveInt
scala> PositiveInt(4)
res0: @@[Int,PositiveInt] = 4
scala> PositiveInt(-4)
res1: @@[Int,PositiveInt] = 4
scala> res0 + res1
res2: Int = 8
But this solution is not perfect.
scala> PositiveInt(5) - PositiveInt(6)
res4: Int = -1
scala> PositiveInt(PositiveInt(5) - PositiveInt(6))
res5: @@[Int,PositiveInt] = 1
To get full solution, you may have to get a real class with full method definition
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments