diff --git a/src/Data/Enum/Gen.purs b/src/Data/Enum/Gen.purs index 86caebd..5e3acc8 100644 --- a/src/Data/Enum/Gen.purs +++ b/src/Data/Enum/Gen.purs @@ -2,17 +2,24 @@ module Data.Enum.Gen where import Prelude -import Control.Monad.Gen (class MonadGen, elements) -import Data.Enum (class BoundedEnum, succ, enumFromTo) -import Data.Maybe (Maybe(..)) +import Control.Monad.Gen (class MonadGen, chooseInt, elements) +import Data.Enum (class BoundedEnum, Cardinality, cardinality, enumFromTo, fromEnum, succ, toEnum) +import Data.Maybe (Maybe(..), fromJust) +import Data.Newtype (unwrap) import Data.NonEmpty ((:|)) +import Partial.Unsafe (unsafePartial) -- | Create a random generator for a finite enumeration. genBoundedEnum :: forall m a. MonadGen m => BoundedEnum a => m a genBoundedEnum = - case succ bottom of - Just a → - let possibilities = enumFromTo a top :: Array a - in elements (bottom :| possibilities) - Nothing → - pure bottom + let topInt = fromEnum (top :: a) + bottomInt = fromEnum (bottom :: a) + enumRange = topInt - bottomInt + in if enumRange == unwrap (cardinality :: Cardinality a) + then unsafePartial $ fromJust <<< toEnum <$> chooseInt bottomInt topInt + else case succ bottom of + Just a → + let possibilities = enumFromTo a top :: Array a + in elements (bottom :| possibilities) + Nothing → + pure bottom