The time is stored in differences between the events.
Thus there is no increase of time information for long,
or even infinite, streams of events.
Further on, the time difference is stored
in the latter of two neighbouring events.
This is necessary for real-time computing
where it is not known whether and when the next event happens.

This function merges the events of two lists into a new event list.
Note that merge compares entire events rather than just start times.
This is to ensure that it is commutative,
one of the properties we test for.

mergeBy is like merge but does not simply use the methods of the Ord class
but allows a custom comparison function.
If in event lists xs and ys there are coinciding elements x and y,
and cmp x y is True,
then x comes before y in mergeBy cmp xs ys.

sort sorts a list of coinciding events,
that is all events but the first one have time difference 0.
normalize sorts all coinciding events in a list
thus yielding a canonical representation of a time ordered list.

We provide discretize and resample for discretizing the time information.
When converting the precise relative event times
to the integer relative event times
we have to prevent accumulation of rounding errors.
We avoid this problem with a stateful conversion
which remembers each rounding error we make.
This rounding error is used to correct the next rounding.
Given the relative time and duration of an event
the function floorDiff creates a State
which computes the rounded relative time.
It is corrected by previous rounding errors.

The resulting event list may have differing time differences
which were equal before discretization,
but the overall timing is uniformly close to the original.

We use floorDiff rather than roundDiff
in order to compute exclusively with non-negative numbers.