import Data.Bifunctor (first) import System.Random (uniformR, RandomGen) uniformEnum :: forall a g. (Enum a, Bounded a, RandomGen g) => g -> (a, g) uniformEnum g = toEnum `first` uniformR ( fromEnum (minBound :: a) , fromEnum (maxBound :: a) ) g