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?

2 Answers 2


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. :) 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).
    – Alexey
    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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.