An enumerated type is a type that can hold one of a finite list of possible values. In Julia, enumerated types are typically called "enum types". For instance, one could use enum types to describe the seven days of the week, the twelve months of the year, the four suits of a standard 52-card deck, or other similar situations.

We can define enumerated types to model the suits and ranks of a standard 52-card deck. The `@enum`

macro is used to define enum types.

```
@enum Suit ♣ ♦ ♥ ♠
@enum Rank ace=1 two three four five six seven eight nine ten jack queen king
```

This defines two types: `Suit`

and `Rank`

. We can check that the values are indeed of the expected types:

```
julia> ♦
♦::Suit = 1
julia> six
six::Rank = 6
```

Note that each suit and rank has been associated with a number. By default, this number starts at zero. So the second suit, diamonds, was assigned the number 1. In the case of `Rank`

, it may make more sense to start the number at one. This was achieved by annotating the definition of `ace`

with a `=1`

annotation.

Enumerated types come with a lot of functionality, such as equality (and indeed identity) and comparisons built in:

```
julia> seven === seven
true
julia> ten ≠ jack
true
julia> two < three
true
```

Like values of any other immutable type, values of enumerated types can also be hashed and stored in `Dict`

s.

We can complete this example by defining a `Card`

type that has a `Rank`

and a `Suit`

field:

```
immutable Card
rank::Rank
suit::Suit
end
```

and hence we can create cards with

```
julia> Card(three, ♣)
Card(three::Rank = 3,♣::Suit = 0)
```

But enumerated types also come with their own `convert`

methods, so we can indeed simply do

```
julia> Card(7, ♠)
Card(seven::Rank = 7,♠::Suit = 3)
```

and since `7`

can be directly converted to `Rank`

, this constructor works out of the box.

We might wish to define syntactic sugar for constructing these cards; implicit multiplication provides a convenient way to do it. Define

```
julia> import Base.*
julia> r::Int * s::Suit = Card(r, s)
* (generic function with 156 methods)
```

and then

```
julia> 10♣
Card(ten::Rank = 10,♣::Suit = 0)
julia> 5♠
Card(five::Rank = 5,♠::Suit = 3)
```

once again taking advantage of the in-built `convert`

functions.