Phantom type

From HaskellWiki

A phantom type is a parametrised type whose parameters do not all appear on the right-hand side of its definition, e.g. from Control.Applicative:

newtype Const a b = Const { getConst :: a }

Here Const is a phantom type, because the b parameter doesn't appear after the = sign.

Phantom types are useful in a variety of contexts: in the standard Data.Fixed module they are used with type classes to encode the precision being used, with smart constructors or GADTs they can encode information about how and where a value can be used, or with more exotic extensions they can be used for encoding bounds checks in the type system.

1 Simple examples

A phantom type will have a declaration that looks something like this:

data FormData a = FormData String

This looks strange since at first it seems the type parameter is unused and could be anything, without affecting the value inside. Indeed, one can write:

This technique is perfect for e.g. escaping user input to a web application. We can ensure with zero overhead that the data is escaped once and only once everywhere that it needs to be, or else we get a compile-time error.

2 The use of a type system to guarantee well-formedness.

We create a Parameterized type in which the parameter does not appear
on the rhs (shameless cutting and pasting from Daan Leijen and Erik Meijer)

but since we only expose the functions our attempts
to create this expression via

constant 1.==. constant "foo"

would fail to typecheck

I believe this technique is used when trying to interface
with a language that would cause a runtime exception if the types
were wrong but would have a go at running the expression first.
(They use it in the context of SQL but I have also seen it in the
context of FLI work.)

-- ChrisAngus

A foundation for embedded languages provides some formal background for embedding typed languages in Haskell, and also its references give a fairly comprehensive survey of uses of phantom types and related techniques.