# Haskell syntax for type definitions: why the equality sign?

I am a bit confused by the choice of Haskell syntax for type definitions, like in

``````data Foo = Bar
``````

Namely: does the equality sign here really mean an equality in some subtle sense, or is it just a random notation choice?

For example, in

``````foo x y = bar y x
``````

the equality is really an equality: if this line is present, `foo a b` and `bar b a` can be used more or less interchangeably in the program. However, `data Foo` and `Bar` probably cannot be used interchangeably after `data Foo = Bar`.

Whenever i resume my attempts to learn Haskell, i am a bit confused by this IMO counter-intuitive syntax and need to look up the documentation to recall the formats of the LHS and the RHS. Are there any alternative syntaxes for type definitions by any chance?

You're right that `data Foo` (or even `Foo`) and `Bar` can't be used interchangeably in Haskell code, but one might argue that type definitions, such as

``````data List a = Nil | Cons a (List a)
``````

can be transformed into an "equation" of the form `List(a) = 1 + a * List(a)`. And you can then start playing with it as if it were an algebraic expression: the equation can be rewritten as `List(a) = 1 / (1-a)`, from which `List(a) = 1 + a + a*a + a*a*a + ...`. See the paper Seven trees in one for a spectacular application, or this SO question for lots more.

This is all very nice of course, but it's not going to help you read data declarations better!

For that, you could consider using Generalized Algebraic Datatypes, aka GADTs. One feature of those is that the types of the constructors are explicitly spelled out, making it clear what each constructor's name is, what types of arguments it takes and what the result type is. And it doesn't use that pesky `=` sign :-)

Your example would be written as:

``````data Foo where
Bar :: Foo
``````

the List example I gave above would be:

``````data List a where
Nil :: List a
Cons :: a -> List a -> List a
``````

and an equivalent of the on-purpose confusingly named `data X = X X X | Y` would be:

``````data X where
X :: X -> X -> X
Y :: X
``````

GADTs, however, are not standard Haskell: they're a GHC extension, and a pretty recent one (so there might still be some bugs), but for your purpose of having an alternate type definition syntax I think they fit the bill just fine.

• GADTs aren't that recent an extension; I would honestly be pretty surprised if any bugs existed in them at this point. :) Commented Aug 1, 2014 at 9:40
• I have realised that if instead of `=`, the type definition was using `::=`, it would look like a rule of a grammar definition in Backus–Naur Form, where type constructors are like expression variables (nonterminal symbols), and value constructors are like literal characters (terminal symbols). Commented Jul 26, 2015 at 8:28

Foo is a type, Bar is a value. It doesn't make sense to speak of exchanging them. Rather, the equality sign expresses that type Foo consists of precisely those values on the right; no more and no less.