universum
universum copied to clipboard
Consider adding a safe version of `toEnum` for `Bounded` types.
toEnum
is partial. If the type is not only Enum
but also Bounded
it's simple enough to implement a non-partial version, e.g.
toEnumSafe :: forall a. (Enum a, Bounded a) => Int -> Maybe a
toEnumSafe i = guard (inBounds i) $> toEnum i where
inBounds = inRange $ join bimap (fromEnum @a) (minBound, maxBound)
{-# INLINE toEnumSafe #-} -- the hope is most of 'inBounds' can be evalueated at compile time if 'a' is known
(inRange
is defined in Data.Ix
)
There are versions of this in relude
and safe
. It's occasionally very useful.