This module provides efficient *half-integers*. That is,
normal integers and integers plus or minus 1/2. These are
sometimes useful for when a value can be an integer, or midway
between two integers.

- data HalfInteger i
- half :: Num i => HalfInteger i
- halve :: i -> HalfInteger i
- double :: HalfInteger i -> i
- toHalfInteger :: (RealFrac x, Integral i) => x -> HalfInteger i
- fromHalfInteger :: (Integral i, Fractional x) => HalfInteger i -> x
- isInteger :: Integral i => HalfInteger i -> Bool

# Documentation

data HalfInteger i Source

The type of half-integers. The bounds are determined by the type
variable. For example, `HalfInteger Int`

has a range half as large
as `Int`

itself. (The `Bounded`

instance correctly reflects this.)
Note that `HalfInteger Integer`

is unbounded, like `Integer`

itself.

`HalfInteger`

values can be constructed as numeric literals
(e.g., `5 :: HalfInteger Int`

), by conversions such as
`fromInteger`

or `fromIntegral`

, or by several functions in this
module. Another common pattern is to write (say) `5 + half`

to
represent 5 1/2. Indeed, the `Show`

instance represents values
in this way.

Beware: The half-integers are *not* closed under multiplication!
For example, `half * half`

should yield 1/4, which is not a valid
`HalfInteger`

. (Currently it yields zero.) Addition and
subtraction, however, *are* closed, and thus yield exact results.

Bounded i => Bounded (HalfInteger i) | |

Eq i => Eq (HalfInteger i) | |

Integral i => Num (HalfInteger i) | |

Ord i => Ord (HalfInteger i) | |

Integral i => Show (HalfInteger i) |

half :: Num i => HalfInteger iSource

Represents 1/2 as a `HalfInteger`

. You can add this to integral
`HalfInteger`

values created in various ways to get the
half-part in.

halve :: i -> HalfInteger iSource

Take an integer and halve its value, yielding a `HalfInteger`

.
This conversion is always exact, and `half . double == id`

.

double :: HalfInteger i -> iSource

Take a `HalfInteger`

and double its value, yielding a normal integer.
This conversion is always exact, and `double . half == id`

.

toHalfInteger :: (RealFrac x, Integral i) => x -> HalfInteger iSource

Convert any number into a `HalfInteger`

. The rounding is somewhat
unpredictable, but

fromHalfInteger :: (Integral i, Fractional x) => HalfInteger i -> xSource

Convert a `HalfInteger`

into some other kind of number.
This conversion is always exact.

isInteger :: Integral i => HalfInteger i -> BoolSource

Returns `True`

if this `HalfInteger`

can be exactly represented
as an ordinary integer, and `False`

if there is a half offset.