If you want a runtime representation of the phantom type you have used, you have to use what we call a singleton. It has precisely one constructor for each ones of the constructors in UnitLength and their types say precisely which constructor we are considering:
data SUnitLength (a :: UnitLength) where
SMeter :: SUnitLength Meter
SKiloMeter :: SUnitLength KiloMeter
SMiles :: SUnitLength Miles
Now that you have this you can for instance write a display function picking the right unit abbreviation depending on the phantom parameter:
display :: Show b => SUnitLength a -> Length a b -> String
display sa l = show (payload l) ++
case sa of
SKiloMeter -> "km"
_ -> "m"
Now, that does not really match your demand: the parameter a is available in the type Length a b but we somehow still have to manufacture the witness by hand. That's annoying. One way to avoid this issue is to define a type class doing that work for us. CUnitLength a tells us that provided a value of type Length a b, we can get a witness SUnitLength a of the shape a has.
class CUnitLength (a :: UnitLength) where
getUnit :: Length a b -> SUnitLength a
It is easy for us to write instances of CUnitLength for the various UnitLength constructors: getUnit can even ignore its argument!
instance CUnitLength Meter where
getUnit _ = SMeter
instance CUnitLength KiloMeter where
getUnit _ = SKiloMeter
instance CUnitLength Miles where
getUnit _ = SMiles
So why bother with getUnit's argument? Well if we remove it, getUnit needs to somehow magically guess which a it is suppose to describe. Sometimes it's possible to infer that ̀a based on the expected type at the call site but sometimes it's not. Having the Length a b argument guarantees that all calls will be unambiguous. We can always recover a simpler getUnit' anyway:
getUnit' :: CUnitLength a => SUnitLength a
getUnit' = getUnit (undefined :: Length a ())
Which leads us to the last definition display' which has the same role as display but does not require the extra argument:
display' :: (CUnitLength a, Show b) => Length a b -> String
display' = display getUnit'
I have put everything (including the LANGUAGE extensions, and the definition of payload to extract a b from Length a b) in a self-contained gist in case you want to play with the code.