Reexports Enum related typeclasses and functions. Also introduces a few useful
helpers to work with Enums.
Note:universe, universeNonEmpty and inverseMap were previously in the
extra modules, but due to their benefit in different use cases. If you imported
Relude.Extra.Enum module, you can remove it now, as these functions are
reexported in the main Relude module.
inverseMap f creates a function that is the inverse of a given function
f. It does so by constructing Map internally for each value f a. The
implementation makes sure that the Map is constructed only once and then
shared for every call.
Memory usage note: don't inverse functions that have types like Int
as their input. In this case the created Map will have huge size.
The complexity of reversed mapping is \mathcal{O}(\log n).
Performance note: make sure to specialize monomorphic type of your functions
that use inverseMap to avoid Map reconstruction.
One of the common inverseMap use-case is inverting the show or a show-like
function.
Example4 expressions
>>> data Color = Red | Green | Blue deriving (Show, Enum, Bounded)>>> parse = inverseMap show :: String -> Maybe Color>>> parse "Red"Just Red>>> parse "Black"Nothing
Correctness note:inverseMap expects injective function as its argument,
i.e. the function must map distinct arguments to distinct values.
Class Enum defines operations on sequentially ordered types.
The enumFrom... methods are used in Haskell's translation of
arithmetic sequences.
Instances of Enum may be derived for any enumeration type (types
whose constructors have no fields). The nullary constructors are
assumed to be numbered left-to-right by fromEnum from 0 through n-1.
See Chapter 10 of the Haskell Report for more details.
For any type that is an instance of class Bounded as well as Enum,
the following should hold:
fromEnum and toEnum should give a runtime error if the
result value is not representable in the result type.
For example, toEnum 7 :: Bool is an error.
enumFrom x = enumFromTo x maxBound
enumFromThen x y = enumFromThenTo x y bound
where
bound | fromEnum y >= fromEnum x = maxBound
| otherwise = minBound
Used in Haskell's translation of [n,n'..]
with [n,n'..] = enumFromThen n n', a possible implementation being
enumFromThen n n' = n : n' : worker (f x) (f x n'),
worker s v = v : worker s (s v), x = fromEnum n' - fromEnum n and
f n y
| n > 0 = f (n - 1) (succ y)
| n < 0 = f (n + 1) (pred y)
| otherwise = y
Used in Haskell's translation of [n,n'..m] with
[n,n'..m] = enumFromThenTo n n' m, a possible implementation
being enumFromThenTo n n' m = worker (f x) (c x) n m,
x = fromEnum n' - fromEnum n, c x = bool (>=) ((x 0)
f n y
| n > 0 = f (n - 1) (succ y)
| n < 0 = f (n + 1) (pred y)
| otherwise = y
and
worker s c v m
| c v m = v : worker s c (s v) m
| otherwise = []
Enum (Fixeda)Defined in base-4.20.2.0 · Data.Fixed
Recall that, for numeric types, succ and pred typically add and subtract
1, respectively. This is not true in the case of Fixed, whose successor
and predecessor functions intuitively return the "next" and "previous" values
in the enumeration. The results of these functions thus depend on the
resolution of the Fixed value. For example, when enumerating values of
resolution 10^-3 of type Milli = Fixed E3,
Example1 expression
>>> succ (0.000 :: Milli)0.001
and likewise
Example1 expression
>>> pred (0.000 :: Milli)-0.001
In other words, succ and pred increment and decrement a fixed-precision
value by the least amount such that the value's resolution is unchanged.
For example, 10^-12 is the smallest (positive) amount that can be added to
a value of type Pico = Fixed E12 without changing its resolution, and so
Example1 expression
>>> succ (0.000000000000 :: Pico)0.000000000001
and similarly
Example1 expression
>>> pred (0.000000000000 :: Pico)-0.000000000001
This is worth bearing in mind when defining Fixed arithmetic sequences. In
particular, you may be forgiven for thinking the sequence
However, this is not true. On the contrary, similarly to the above
implementations of succ and pred, enumFromTo :: Pico -> Pico -> [Pico]
has a "step size" of 10^-12. Hence, the list [1..10] :: [Pico] has
the form
The Bounded class is used to name the upper and lower limits of a
type. Ord is not a superclass of Bounded since types that are not
totally ordered may also have upper and lower bounds.
The Bounded class may be derived for any enumeration type;
minBound is the first constructor listed in the data declaration
and maxBound is the last.
Bounded may also be derived for single-constructor datatypes whose
constituent types are in Bounded.