I wondered whether `[]`

is a type, since it would be a natural notation for an empty polymorphic variant type. At first it doesn’t seem to be:

```
# let f (x : []) : [] = x;;
Error: Syntax error: type expected.
```

But this works:

```
# type foo = [];;
type foo = []
# let f (x : foo) : foo = x;;
val f : foo -> foo = <fun>
```

However, it doesn’t seem to be an empty type:

```
# let f (x : foo) = match x with _ -> .;;
Error: This match case could not be refuted.
Here is an example of a value that would reach it: []
```

This error message suggests that `[]`

is an element of the type `[]`

, and indeed it seems to be, at least as long as the type was given a name:

```
# let y : foo = [];;
val y : foo = []
# let y : [] = [];;
Error: Syntax error
# let f (x : foo) = match x with [] -> 3;;
val f : foo -> int = <fun>
```

Normally `[]`

denotes the empty list, so I thought maybe `[]`

was “the type of empty lists”. But if so, these “lists” don’t seem to have anything to do with ordinary ones:

```
# 3 :: y;;
Error: This expression has type foo but an expression was expected of type
int list
# let z : 'a list = [];;
val z : 'a list = []
# y = z;;
Error: This expression has type 'a list but an expression was expected of type
foo
```

I am very confused. Is `[]`

a type, as it seems to sort of be? If so, what type is it, and why does it only work in some places and not others? If not, what is going on?