{-# LANGUAGE Safe #-}
module Relude.Extra.Enum
( next
, prev
, safeToEnum
) where
import Relude
next :: (Eq a, Bounded a, Enum a) => a -> a
next :: a -> a
next 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 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 #-}
safeToEnum :: forall a . (Bounded a, Enum a) => Int -> Maybe a
safeToEnum :: Int -> Maybe a
safeToEnum 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 #-}