In Haskell, I believe that it is possible to alias a type in such a way that the compiler does not allow references between the aliased type and the unaliased type. According to this stack overflow question, one can use Haskell’s newtype like so:
newtype Feet = Feet Double
newtype Cm = Cm Double
where Feet and Cm will behave like Double values, but attempting to multiply a Feet value and a Cm value will result in a compiler error.
EDIT: Ben pointed out in the comments that this above definition in Haskell is insufficient. Feet and Cm will be new types, on which there will be no functions defined. Doing a bit more research, I found that the following will work:
newtype Feet = Feet Double deriving (Num)
newtype Cm = Cm Double deriving (Num)
This creates a new type that derives from the existing Num type (requires using switch: -XGeneralizedNewtypeDeriving). Of course, these new types will be even more valuable deriving from other types such as Show, Eq, etc. but this is the minimum required to correctly evaluate Cm 7 * Cm 9.
Both Haskell and Scala have type, which simply aliases an existing type and allows nonsensical code such as this example in Scala:
type Feet = Double
type Cm = Double
val widthInFeet: Feet = 1.0
val widthInCm: Cm = 30.48
val nonsense = widthInFeet * widthInCm
def getWidthInFeet: Feet = widthInCm
Does Scala have a newtype equivalent, assuming that this does what I think it does?
Yeah you using something known as Unboxed Tagged Types in scala.
This is how Tagged is defined:
This allows you to do something like this
to also add CM
If you want to restrict multiplication to only Feet then you could write a typeclass type multiplication function
you can then do
this is the best Scala can do
To learn more about the boxed type check out
http://eed3si9n.com/learning-scalaz-day3