[Haskell-beginners] Would you shed light on "undefined values" please?

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

Costello, Roger L. wrote:
> In this book [1] 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 

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


Best regards,
Heinrich Apfelmus


More information about the Beginners mailing list