Heinrich Apfelmus apfelmus at quantentunnel.de
Fri Jun 24 09:59:58 CEST 2011

```Costello, Roger L. wrote:
> In this book  the author defines the term "bottom":
>
>    In order that we can say that, without exception, every
>    syntactically well-formed expression denotes a value,
>    it is convenient to introduce a special symbol (upside
>    down T), pronounced 'bottom', to stand for the undefined
>    value of a particular type. In particular, the value of
>    infinity is the undefined value (bottom) of type Integer,
>    and 1/0 is the undefined value (bottom) of type Float.
>    Hence we can assert that 1/0 = bottom.
>
> He defines infinity as this:
>
>     infinity :: Integer
>     infinity = infinity + 1
>
> The author says this when discussing the Bool datatype:
>
>     It follows that there are not two but three Boolean
>     values, namely False, True, and bottom. In fact, every
>     datatype declaration introduces an extra anonymous
>     value, the undefined value of the datatype.
>
> What is the undefined value (bottom) of type Bool?
>
> What is the undefined value (bottom) of type String?
>
> If I create my own datatype:
>
> data MyBool = F | T
>
> What is the undefined value (bottom) of type MyBool?
>
> I am not clear why "bottom" is an important concept. Would you explain please?

Bottom, _|_, is a little trick to do precisely what Bird said, namely
"make every expression denote a value".

As you know, in Haskell, you can reason about programs by comparing
their values. For instance, we have

4+5 = 10-1 = length [0..8] = sum (replicate 3 3)

because all these expressions denote the value 9, a number. But there
are expressions that should be numbers, yet aren't. Examples:

sum [1..]
let loop = 2-loop in loop

What value do they have? Certainly not 1 or 5 or some other number. We
do want them to have a value, though, so we have to invent one: _|_ .
More precisely, every expression that does not terminate denotes the
value _|_.

(Actually, we have to invent one for every type: _|_ :: String, _|_ ::
Bool, _|_ :: MyBool, etc. because we can only compare values of the same
type.)

The rules for calculating with _|_ are presented here: