[Haskell-cafe] phantom types and record syntax

Chaddaï Fouché chaddai.fouche at gmail.com
Thu Jun 18 17:48:24 UTC 2015

Le jeu. 18 juin 2015 à 04:45, Dimitri DeFigueiredo <defigueiredo at ucdavis.edu>
a écrit :

>  I am surprised that this program compiles in GHC:
> snip

> 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:

This is faulty reasoning because it imply that a value changed type in your
code, based on your understanding that the record syntax is "changing" a

This is not the case ! Haskell is functional, immutability is the rule. The
record syntax is just a shortcut to create a new value sharing some of its
parts with the old value. It is thus perfectly normal that the type of this
new value can be different of the type of the old value if no other
constraint prevent this (and Phantom types are by essence unconstrained by
the value, that is why they're "Phantom").

> But this makes me unwilling to use phantom types for security as I would
> be worried of unwittingly making the conversion.
The value of Phantom types is generally only displayed if you make them
abstract types, since the only way to constrain the phantom type is by
imposing restrictive signatures for your handling functions (and then using
those restricted functions)... This is why you usually won't export the
constructors, only smart constructors that can only produce a precise type
of value with the right phantom type. In these conditions, you can't
"unwittingly make a conversion" and your API impose a safe pattern of use,
helped by the type system to interdict unsafe combination without any
runtime cost.

> Could somebody sprinkle some insight into why this is "converted
> automatically" for phantom types?
> Is there another way around this?
>  <http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe>

As I said, your perspective is wrong : there is no "conversion" here,
simply a new value with a new type. I really fail to see why you would want
your program to fail to compile, your "sanitize" is exactly the kind of
function Phantom types are for : supposing you can only create "Username
UserSupplied" with your API, and a part of your API only accept "Username
Safe", you'll need a function like sanitize to bridge those two parts.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150618/2a9a590a/attachment.html>

More information about the Haskell-Cafe mailing list