# Difference between revisions of "Phantom type"

m (haskell) |
BrettGiles (talk | contribs) (Converting extra stuff from HaWiki page) |
||

Line 14: | Line 14: | ||

The term "phantom type" already has an established use. A simple case is described (somewhat messily) in [[http://haskell.org/hawiki/PhantomTypes]]. [[http://www.google.com/search?hl=en&q=%22Phantom+types%22 This]] Google search lists many other uses of the term in that vein. |
The term "phantom type" already has an established use. A simple case is described (somewhat messily) in [[http://haskell.org/hawiki/PhantomTypes]]. [[http://www.google.com/search?hl=en&q=%22Phantom+types%22 This]] Google search lists many other uses of the term in that vein. |
||

+ | |||

+ | ==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) |
||

+ | <haskell> |
||

+ | data Expr a = Expr PrimExpr |
||

+ | |||

+ | constant :: Show a => a -> Expr a |
||

+ | (.+.) :: Expr Int -> Expr Int -> Expr Int |
||

+ | (.==.) :: Eq a=> Expr a-> Expr a-> Expr Bool |
||

+ | (.AND.):: Expr Bool -> Expr Bool-> Expr Bool |
||

+ | |||

+ | data PrimExpr |
||

+ | = BinExpr BinOp PrimExpr PrimExpr |
||

+ | | UnExpr UnOp PrimExpr |
||

+ | | ConstExpr String |
||

+ | |||

+ | data BinOp |
||

+ | = OpEq | OpAnd | OpPlus | ... |
||

+ | </haskell> |
||

+ | i.e. the datatype is such that we could get garbage such as |
||

+ | <haskell> |
||

+ | BinExpr OpEq (ConstExpr "1") (ConstExpr "\"foo\"") |
||

+ | </haskell> |
||

+ | but since we only expose the functions our attempts |
||

+ | to create this expression via |
||

+ | <haskell> |
||

+ | constant 1 .==. constant "foo" |
||

+ | </haskell> |
||

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

+ | |||

+ | [http://www.brics.dk/RS/02/34/ 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. |
||

+ | |||

+ | ---- |
||

[[Category:Idioms]] |
[[Category:Idioms]] |

## Revision as of 13:51, 30 September 2006

A **phantom type** is a type used only to construct other types;
its values are never used. Phantom types are used in Type arithmetic, and for
encoding bounds checks in the type system.

An extension to Haskell 98 supported by GHC allows you to define datatypes without any constructors (and therefore no values other than bottom):

```
data MyType
```

This lets the compiler recognize phantom types and ensure they aren't used improperly.

The term "phantom type" already has an established use. A simple case is described (somewhat messily) in [[1]]. [This] Google search lists many other uses of the term in that vein.

## 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)

```
data Expr a = Expr PrimExpr
constant :: Show a => a -> Expr a
(.+.) :: Expr Int -> Expr Int -> Expr Int
(.==.) :: Eq a=> Expr a-> Expr a-> Expr Bool
(.AND.):: Expr Bool -> Expr Bool-> Expr Bool
data PrimExpr
= BinExpr BinOp PrimExpr PrimExpr
| UnExpr UnOp PrimExpr
| ConstExpr String
data BinOp
= OpEq | OpAnd | OpPlus | ...
```

i.e. the datatype is such that we could get garbage such as

```
BinExpr OpEq (ConstExpr "1") (ConstExpr "\"foo\"")
```

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.