module Relude.Extra.Enum
( universe
, inverseMap
, next
, prev
, prec
, safeToEnum
) where
import Relude
import Relude.Extra.Tuple (mapToFst)
import qualified Data.Map.Strict as M
universe :: (Bounded a, Enum a) => [a]
universe :: [a]
universe = [a
forall a. Bounded a => a
minBound .. a
forall a. Bounded a => a
maxBound]
{-# INLINE universe #-}
inverseMap
:: forall a k .
(Bounded a, Enum a, Ord k)
=> (a -> k)
-> (k -> Maybe a)
inverseMap :: (a -> k) -> k -> Maybe a
inverseMap f :: a -> k
f = \k :: k
k -> k -> Map k a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup k
k Map k a
dict
where
dict :: M.Map k a
dict :: Map k a
dict = [(k, a)] -> Map k a
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(k, a)] -> Map k a) -> [(k, a)] -> Map k a
forall a b. (a -> b) -> a -> b
$ (a -> (k, a)) -> [a] -> [(k, a)]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> k) -> a -> (k, a)
forall a b. (a -> b) -> a -> (b, a)
mapToFst a -> k
f) ((Bounded a, Enum a) => [a]
forall a. (Bounded a, Enum a) => [a]
universe @a)
{-# INLINE inverseMap #-}
next :: (Eq a, Bounded a, Enum a) => a -> a
next :: a -> a
next e :: a
e
| a
e a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Bounded a => a
maxBound = a
forall a. Bounded a => a
minBound
| Bool
otherwise = a -> a
forall a. Enum a => a -> a
succ a
e
{-# INLINE next #-}
prev :: (Eq a, Bounded a, Enum a) => a -> a
prev :: a -> a
prev e :: a
e
| a
e a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Bounded a => a
minBound = a
forall a. Bounded a => a
maxBound
| Bool
otherwise = a -> a
forall a. Enum a => a -> a
pred a
e
{-# INLINE prev #-}
prec :: (Eq a, Bounded a, Enum a) => a -> a
prec :: a -> a
prec = a -> a
forall a. (Eq a, Bounded a, Enum a) => a -> a
prev
{-# DEPRECATED prec "Use 'prev' instead, it has more idiomatic and common name" #-}
safeToEnum :: forall a . (Bounded a, Enum a) => Int -> Maybe a
safeToEnum :: Int -> Maybe a
safeToEnum i :: Int
i = Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (a -> Int
forall a. Enum a => a -> Int
fromEnum @a a
forall a. Bounded a => a
minBound Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= a -> Int
forall a. Enum a => a -> Int
fromEnum @a a
forall a. Bounded a => a
maxBound) Maybe () -> a -> Maybe a
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Int -> a
forall a. Enum a => Int -> a
toEnum Int
i
{-# INLINE safeToEnum #-}