Hi All,

My apologies if this is not the right forum, but am not satisfied with my current understanding.

I am surprised that this program compiles in GHC:

-----
data UserSupplied  = UserSupplied -- i.e. unsafe
data Safe          = Safe

data Username a = Username { first :: String, last :: String}

sanitize :: Username UserSupplied -> Username Safe
sanitize name = name { first = "John" }

main = putStrLn "Hi!"
-----

My trouble is that it seems the record syntax is *implicitly* converting from one type to the other. It seems I would have to remove the phantom type by adding a tag to avoid this:

-----
data Username a = Username { first :: String, last :: String, tag :: a }

sanitize :: Username UserSupplied -> Username Safe
sanitize name = name { first = "John" } -- FAIL as expected!! :-)
-----

But this makes me unwilling to use phantom types for security as I would be worried of unwittingly making the conversion.

Could somebody sprinkle some insight into why this is "converted automatically" for phantom types?
Is there another way around this?


Thanks!


Dimitri