| Copyright | (c) 2021-2023 Kowainik |
|---|---|
| License | MIT |
| Maintainer | Kowainik <xrom.xkov@gmail.com> |
| Stability | Stable |
| Portability | Portable |
| Safe Haskell | Safe |
| Language | Haskell2010 |
Relude.Enum
Description
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.
Since: 1.0.0.0
Synopsis
- universe :: (Bounded a, Enum a) => [a]
- universeNonEmpty :: (Bounded a, Enum a) => NonEmpty a
- inverseMap :: (Bounded a, Enum a, Ord k) => (a -> k) -> k -> Maybe a
- class Enum a where
- succ :: a -> a
- pred :: a -> a
- toEnum :: Int -> a
- fromEnum :: a -> Int
- enumFrom :: a -> [a]
- enumFromThen :: a -> a -> [a]
- enumFromTo :: a -> a -> [a]
- enumFromThenTo :: a -> a -> a -> [a]
- class Bounded a where
- boundedEnumFrom :: (Enum a, Bounded a) => a -> [a]
- boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a]
Useful combinators for Enums
universe :: (Bounded a, Enum a) => [a] #
Returns all values of some Bounded Enum in ascending order.
>>>universe :: [Bool][False,True]
>>>universe @Ordering[LT,EQ,GT]
>>>data TrafficLight = Red | Blue | Green deriving (Show, Enum, Bounded)>>>universe :: [TrafficLight][Red,Blue,Green]
>>>data Singleton = Singleton deriving (Show, Enum, Bounded)>>>universe @Singleton[Singleton]
Since: 0.1.0
universeNonEmpty :: (Bounded a, Enum a) => NonEmpty a #
Like universe, but returns NonEmpty list of some enumeration
>>>universeNonEmpty :: NonEmpty BoolFalse :| [True]
>>>universeNonEmpty @OrderingLT :| [EQ,GT]
>>>data TrafficLight = Red | Blue | Green deriving (Show, Eq, Enum, Bounded)>>>universeNonEmpty :: NonEmpty TrafficLightRed :| [Blue,Green]
>>>data Singleton = Singleton deriving (Show, Eq, Enum, Bounded)>>>universeNonEmpty @SingletonSingleton :| []
Since: 0.7.0.0
inverseMap :: (Bounded a, Enum a, Ord k) => (a -> k) -> k -> Maybe a #
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.
>>>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.
Typical usage of this function looks like this:
data GhcVer
= Ghc802
| Ghc822
| Ghc844
| Ghc865
| Ghc881
deriving (Eq, Ord, Show, Enum, Bounded)
showGhcVer :: GhcVer -> Text
showGhcVer = \case
Ghc802 -> "8.0.2"
Ghc822 -> "8.2.2"
Ghc844 -> "8.4.4"
Ghc865 -> "8.6.5"
Ghc881 -> "8.8.1"
parseGhcVer :: Text -> Maybe GhcVer
parseGhcVer = inverseMap showGhcVer
Since: 0.1.1
Base reexports
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:
- The calls
andsuccmaxBoundshould result in a runtime error.predminBound fromEnumandtoEnumshould give a runtime error if the result value is not representable in the result type. For example,is an error.toEnum7 ::BoolenumFromandenumFromThenshould be defined with an implicit bound, thus:
enumFrom x = enumFromTo x maxBound
enumFromThen x y = enumFromThenTo x y bound
where
bound | fromEnum y >= fromEnum x = maxBound
| otherwise = minBoundMethods
Successor of a value. For numeric types, succ adds 1.
Predecessor of a value. For numeric types, pred subtracts 1.
Convert from an Int.
Convert to an Int.
It is implementation-dependent what fromEnum returns when
applied to a value that is too large to fit in an Int.
Used in Haskell's translation of [n..] with [n..] = enumFrom n,
a possible implementation being enumFrom n = n : enumFrom (succ n).
Examples
enumFrom 4 :: [Integer] = [4,5,6,7,...]
enumFrom 6 :: [Int] = [6,7,8,9,...,maxBound :: Int]
enumFromThen :: a -> a -> [a] #
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
Examples
enumFromThen 4 6 :: [Integer] = [4,6,8,10...]
enumFromThen 6 2 :: [Int] = [6,2,-2,-6,...,minBound :: Int]
enumFromTo :: a -> a -> [a] #
Used in Haskell's translation of [n..m] with
[n..m] = enumFromTo n m, a possible implementation being
enumFromTo n m
| n <= m = n : enumFromTo (succ n) m
| otherwise = []
Examples
enumFromTo 6 10 :: [Int] = [6,7,8,9,10]
enumFromTo 42 1 :: [Integer] = []
enumFromThenTo :: a -> a -> a -> [a] #
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 = []
Examples
enumFromThenTo 4 2 -6 :: [Integer] = [4,2,0,-2,-4,-6]
enumFromThenTo 6 8 2 :: [Int] = []
Instances
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.
Instances
| Bounded Extension | |
| Bounded All | @since base-2.01 |
| Bounded Any | @since base-2.01 |
| Bounded Associativity | @since base-4.9.0.0 |
Defined in GHC.Internal.Generics | |
| Bounded DecidedStrictness | @since base-4.9.0.0 |
Defined in GHC.Internal.Generics | |
| Bounded SourceStrictness | @since base-4.9.0.0 |
Defined in GHC.Internal.Generics | |
| Bounded SourceUnpackedness | @since base-4.9.0.0 |
Defined in GHC.Internal.Generics | |
| Bounded Int16 | @since base-2.01 |
| Bounded Int32 | @since base-2.01 |
| Bounded Int64 | @since base-2.01 |
| Bounded Int8 | @since base-2.01 |
| Bounded Word16 | @since base-2.01 |
| Bounded Word32 | @since base-2.01 |
| Bounded Word64 | @since base-2.01 |
| Bounded Word8 | @since base-2.01 |
| Bounded Ordering | @since base-2.01 |
| Bounded Undefined # | |
| Bounded I8 | |
| Bounded FPFormat | |
| Bounded () | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| Bounded Bool | @since base-2.01 |
| Bounded Char | @since base-2.01 |
| Bounded Int | @since base-2.01 |
| Bounded Levity | @since base-4.16.0.0 |
| Bounded VecCount | @since base-4.10.0.0 |
| Bounded VecElem | @since base-4.10.0.0 |
| Bounded Word | @since base-2.01 |
| Bounded a => Bounded (First a) | Since: base-4.9.0.0 |
| Bounded a => Bounded (Last a) | Since: base-4.9.0.0 |
| Bounded a => Bounded (Max a) | Since: base-4.9.0.0 |
| Bounded a => Bounded (Min a) | Since: base-4.9.0.0 |
| Bounded m => Bounded (WrappedMonoid m) | Since: base-4.9.0.0 |
Defined in Data.Semigroup | |
| Bounded a => Bounded (Identity a) | @since base-4.9.0.0 |
| Bounded a => Bounded (Down a) | Swaps @since base-4.14.0.0 |
| Bounded a => Bounded (Dual a) | @since base-2.01 |
| Bounded a => Bounded (Product a) | @since base-2.01 |
| Bounded a => Bounded (Sum a) | @since base-2.01 |
| Bounded a => Bounded (Solo a) | |
| Bounded (Proxy t) | @since base-4.7.0.0 |
| (Bounded a, Bounded b) => Bounded (a, b) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| Bounded a => Bounded (Const a b) | @since base-4.9.0.0 |
| (Applicative f, Bounded a) => Bounded (Ap f a) | @since base-4.12.0.0 |
| (Bounded a, Bounded b, Bounded c) => Bounded (a, b, c) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d) => Bounded (a, b, c, d) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| Bounded (f (g a)) => Bounded (Compose f g a) | Since: base-4.19.0.0 |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e) => Bounded (a, b, c, d, e) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f) => Bounded (a, b, c, d, e, f) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g) => Bounded (a, b, c, d, e, f, g) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h) => Bounded (a, b, c, d, e, f, g, h) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i) => Bounded (a, b, c, d, e, f, g, h, i) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j) => Bounded (a, b, c, d, e, f, g, h, i, j) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k) => Bounded (a, b, c, d, e, f, g, h, i, j, k) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k, Bounded l) => Bounded (a, b, c, d, e, f, g, h, i, j, k, l) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m) => Bounded (a, b, c, d, e, f, g, h, i, j, k, l, m) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n) => Bounded (a, b, c, d, e, f, g, h, i, j, k, l, m, n) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
| (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n, Bounded o) => Bounded (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) | @since base-2.01 |
Defined in GHC.Internal.Enum | |
boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] #
boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] #