One of the first things to confuse me about Haskell was the number of keywords related to types. The five (I know, 5 isn’t *that* many) I’ve counted in Haskell 98 are `data`

{.haskell}, `type`

{.haskell}, `newtype`

{.haskell}, `instance`

{.haskell}, and `class`

{.haskell}. I was unable to find a comprehensive discussion of what each of them means and how they are related to each other. I’ll break these keywords up linto 2 related sets. `data`

{.haskell}, `type`

{.haskell}, and `newtype`

{.haskell} are all ways to declare a new type. `instance`

{.haskell} and `class`

{.haskell} are slightly different. Let’s take a closer look at them.

`data`

{.haskell} is used to declare a new algebraic data type. We can use it to create a boolean or, in this case, the maybe monad:

```
data Bool = True | False
data Maybe a = Nothing | Just a
```

`type`

{.haskell} is used to create an alias for an algebraic data type. A good example of this is included in the Prelude:

`type String = [Char]`

`newtype`

{.haskell} acts similarly to `type`

{.haskell} with a syntax akin to `data`

{.haskell}. Thus we can write the following:

```
newtype Radius = Radius Double
data Diameter = Diameter Double
```

Okay, so what’s the difference between newtype and data? Three things (that I’m aware of):

`newtype`

{.haskell} can only have a single constructor taking a single argument.`newtype`

{.haskell} creates a strict value constructor and`type`

{.haskell} creates a lazy one (see [1]).`newtype`

{.haskell} introduces no runtime overhead.

A typeclass is a way to guarantee that a type implements certain functions (or data). A type is declared to implement the functions using the keyword `instance`

{.haskell}. An example will be helpful:

```
--Normally I would use Double, but Int's will be easier to read
type Point = (Int, Int)
data Triangle = Triangle Point Point Point deriving (Show)
data Square = Square Point Point Point Point deriving (Show)
class Shape a where
rotate :: a -> a
simple :: a
instance Shape Triangle where
rotate (Triangle x y z) = Triangle z x y
simple = Triangle (0, 0) (1, 0) (0, 1)
instance Shape Square where
rotate (Square w x y z) = Square z w x y
simple = Square (0, 0) (1, 0) (1, 1) (0, 1)
```

As you can see, we first define 3 simple types. Next, the ”`class Shape ...`

{.haskell}” bit, that’s the typeclass definition. All we’re doing is telling the compiler what must be defined for an instance of `Shape`

{.haskell}. With the `instance`

{.haskell} keyword, we make our classes instances of `Shape`

{.haskell} by defining the necessary stuff (i.e. rotate and simple). Let’s try it in GHCi:

```
Prelude> :l shape.hs
[1 of 1] Compiling Main. ( shape.hs, interpreted )
*Main> simple :: Square
Square (0,0) (1,0) (1,1) (0,1)
*Main> rotate it
Square (0,1) (0,0) (1,0) (1,1)
*Main> simple :: Triangle
Triangle (0,0) (1,0) (0,1)
*Main> rotate it
Triangle (0,1) (0,0) (1,0)
*Main> rotate it
Triangle (1,0) (0,1) (0,0)
```

Cool! Because `Square`

{.haskell} and `Triangle`

{.haskell} instantiate `Shape`

{.haskell}, we know that we can call rotate on them. That’s all a typeclass does. I tend to think of them as an interface or a contract.

Remember, `data`

{.haskell}, `type`

{.haskell} and `newtype`

{.haskell} are about making types. `instance`

{.haskell} and `class`

{.haskell} are about making typeclasses.

PS, there’s another keyword, `deriving`

{.haskell}, that could fit in this discussion. It seems less confusing to *me*, so I won’t cover it.