I like the idea of Haskell type synonyms, because they allow for distinguishing between abstract datatypes that share underlying representations. Unfortunately, when I write a program like
data Vector a = Vec a a
-- Some definitions here about (+) and (*) for Vector ...
type Position = Vector Float
type Velocity = Vector Float
type Time = Float
step :: Position -> Velocity -> Time -> Position
step p v dt = p + v*dt
p :: Position
p = Vec 0.0 0.0
v :: Velocity
v = Vec 1.0 1.0
p' = step v p 0.01
This is perfectly valid Haskell code, despite v and p being in the wrong spots. I would like to strengthen the distinction between type synonyms, such that they still share underlying representation, but are not accepted as each other in function application. Is this possible?
You could make
Vectora phantom type as follows:Now, you can define instances of
PositionandVelocitylike you'd normally do:However, it won't allow you to use them interchangeably:
You can also make things more precise by using
DataKindsandKindSignatures:Hope that helps.