A Discrete
type is a set X with at least one element, along with two
functions, succ
:: X -> Maybe
X
and pred
:: X -> Maybe
X
,
such that all inhabitants of the set X can be constructed given at least
a single element of the set and these two functions. The following must hold:
pred
>=>
succ
>=>
pred
= pred
succ
>=>
pred
>=>
succ
= succ
This means that Int
is a discrete type, because given any x :: Int
, one
can construct any other Int
with the following functions:
succ
x = if x ==
maxBound
then Nothing
else Just
(x +
1)
pred
x = if x ==
minBound
then Nothing
else Just
(x -
1)
This also means that something like Double
is not a discrete type, because
there are no such functions succ
and pred
that given any value of type Double
can allow the construction of all values of type Double
.
Discrete
acts as a replacement for GHC.Enum.Enum
. The motivation for
Discrete
is two-fold: firstly, totality of all typeclass instances, and
secondly, that GHC.Enum.Enum
is a typeclass that does too many things,
and does them poorly. If succ
or pred
are called on maxBound
or minBound
, respectively, the result will be Nothing
.