-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | enumerate all the values in a finite type (automatically) -- -- provides (1) a typeclass for enumerating all values in a finite type, -- (2) a generic instance for automatic deriving, and (3) helpers that -- reify functions (partial or total, monadic or pure) into a Map. @package enumerate @version 0.1.1 module Data.Enumerate.Extra -- |
--   failed = throwM . userError
--   
failed :: (MonadThrow m) => String -> m a -- | generalize a function that fails with Nothing. maybe2throw :: (a -> Maybe b) -> (forall m. MonadThrow m => a -> m b) -- | generalize a function that fails with []. list2throw :: (a -> [b]) -> (forall m. MonadThrow m => a -> m b) -- | generalize a function that fails with Left. either2throw :: (a -> Either SomeException b) -> (forall m. MonadThrow m => a -> m b) -- | specialization throw2maybe :: (forall m. MonadThrow m => a -> m b) -> (a -> Maybe b) -- | specialization throw2either :: (forall m. MonadThrow m => a -> m b) -> (a -> Either SomeException b) -- | specialization throw2list :: (forall m. MonadThrow m => a -> m b) -> (a -> [b]) -- | makes an *unsafely*-partial function (i.e. a function that throws -- exceptions or that has inexhaustive pattern matching) into a -- *safely*-partial function (i.e. that explicitly returns in a monad -- that supports failure). totalizeFunction :: (NFData b, MonadThrow m) => (a -> b) -> (a -> m b) -- | handles the following exceptions: -- -- defaultPartialityHandlers :: (MonadThrow m) => [Handler (m a)] -- | Evaluate a value to normal form and throwM any exceptions are -- thrown during evaluation. For any error-free value, spoon = -- Just. -- -- taken from the spoon package. spoonWith :: (NFData a, MonadThrow m) => [Handler (m a)] -> a -> m a -- | the eliminator as a function and the introducer as a string -- -- helper for declaring Show instances of datatypes without visible -- constructors (like Map which is shown as an list). showsPrecWith :: (Show a, Show b) => String -> (a -> b) -> Int -> a -> ShowS int2natural :: Int -> Natural -- | the power set of a set of values. -- --
--   >>> (powerset2matrix . powerSet . Set.fromList) [1..3]
--   [[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
--   
powerSet :: (Ord a) => Set a -> Set (Set a) -- |
--   >>> (powerset2matrix . dropEach . Set.fromList) [1..3]
--   [[1,2],[1,3],[2,3]]
--   
dropEach :: (Ord a) => Set a -> Set (Set a) -- | convert a power set to an isomorphic matrix, sorting the entries. -- -- (for doctest) powerset2matrix :: Set (Set a) -> [[a]] -- | see the Enumerable class for documentation. -- -- see Data.Enumerate.Example for examples. -- -- can also help automatically derive QuickCheck -- instances: -- --
--   newtype SmallNatural = ...
--   instance Enumerable SmallNatural where ...
--   newtype SmallString = ...
--   instance Enumerable SmallString where  ...
--   data T = C0 | C1 () Bool SmallNatural SmallString | C2 ...
--   instance Arbitrary T where arbitrary = elements enumerated
--   
-- -- background on Generics: -- -- -- -- also provides instances for: -- -- -- -- related packages: -- -- module Data.Enumerate.Types -- | enumerate the set of all values in a (finitely enumerable) type. -- enumerates depth first. -- -- generalizes Enums to any finite/discrete type. an Enumerable is -- either: -- -- -- -- can be implemented automatically via its Generic instance. -- -- laws: -- -- -- -- (Bounded constraint elided for convenience, but relevant.) -- -- ("inputs" a type, outputs a list of values). class Enumerable a where enumerated = to <$> genumerated cardinality _ = genericLength (enumerated :: [a]) enumerated :: Enumerable a => [a] cardinality :: Enumerable a => proxy a -> Natural -- | a (safely-)partial function. i.e. a function that: -- -- type Partial a b = forall m. MonadThrow m => a -> m b -- | "Generic Enumerable", lifted to unary type constructors. class GEnumerable f genumerated :: GEnumerable f => [f x] gcardinality :: GEnumerable f => proxy f -> Natural -- | empty list -- | singleton list -- | call enumerated -- | multiply lists with concatMap -- | add lists with (<>) -- | ignore selector metadata -- | ignore constructor metadata -- | ignore datatype metadata -- | see "Data.Enumerate.Reify.getJectivityM" data Jectivity Injective :: Jectivity Surjective :: Jectivity Bijective :: Jectivity -- | wrap any (Bounded a, Enum a) to be a Enumerable via -- boundedEnumerated. -- -- (avoids OverlappingInstances). newtype WrappedBoundedEnum a WrappedBoundedEnum :: a -> WrappedBoundedEnum a [unwrapBoundedEnum] :: WrappedBoundedEnum a -> a -- |
--   >>> (maxBound::Int8) - (minBound::Int8)
--   256
--   
-- |
--   >>> (maxBound::Int16) - (minBound::Int16)
--   65535
--   
-- | there are only a million (1,114,112) characters. -- --
--   >>> ord minBound
--   0
--   
-- --
--   >>> ord maxBound
--   1114111
--   
-- --
--   >>> length [chr 0..]
--   1114112
--   
-- | the sum type. -- -- the cardinality is the sum of the cardinalities of a -- and b. -- | the product type. -- -- the cardinality is the product of the cardinalities of -- a and b. -- | the cardinality is product of cardinalities. -- | the cardinality is 1. -- | the cardinality is the cardinality of the powerSet of -- a, i.e. 2^|a|. warning: it grows quickly. don't try -- to take the power set of Char! or even Word8. -- -- the cardinality call is efficient (depending on the efficiency -- of the base type's call). you should be able to safely call -- enumerateBelow, unless the arithmetic itself becomes too large. -- | for non-Generic Bounded Enums: -- --
--   instance Enumerable _ where
--    enumerated = boundedEnumerated
--    cardinality = boundedCardinality
--   
boundedEnumerated :: (Bounded a, Enum a) => [a] -- | for non-Generic Bounded Enums. -- -- behavior may be undefined when the cardinality of a is larger -- than the cardinality of Int. this should be okay, as -- Int is at least as big as Int64, which is at least -- as big as all the monomorphic types in base that instantiate -- Bounded. you can double-check with: -- --
--   >>> boundedCardinality (const(undefined::Int))   -- platform specific
--   18446744073709551616
--   
-- --
--   -- i.e. 1 + 9223372036854775807 - -9223372036854775808
--   
-- -- works with non-zero-based Enum instances, like Int64 or a -- custom toEnum/fromEnum. assumes the enumeration's numbering -- is contiguous, e.g. if fromEnum 0 and fromEnum 2 -- both exist, then fromEnum 1 should exist too. boundedCardinality :: (Bounded a, Enum a) => proxy a -> Natural -- | for non-Generic Enums: -- --
--   instance Enumerable ... where
--    enumerated = enumEnumerated
--   
-- -- the enum should still be bounded. enumEnumerated :: (Enum a) => [a] -- | for non-Generic Bounded Indexed (Ix) types: -- --
--   instance Enumerable _ where
--    enumerated = indexedEnumerated
--    cardinality = indexedCardinality
--   
indexedEnumerated :: (Bounded a, Ix a) => [a] -- | for non-Generic Bounded Indexed (Ix) types. indexedCardinality :: (Bounded a, Ix a) => proxy a -> Natural -- | enumerate only when the cardinality is small enough. returns the -- cardinality when too large. -- --
--   >>> enumerateBelow 2 :: Either Natural [Bool]
--   Left 2
--   
-- --
--   >>> enumerateBelow 100 :: Either Natural [Bool]
--   Right [False,True]
--   
-- -- useful when you've established that traversing a list below some -- length and consuming its values is reasonable for your application. -- e.g. after benchmarking, you think you can process a billion entries -- within a minute. enumerateBelow :: (Enumerable a) => Natural -> Either Natural [a] -- | enumerate only when completely evaluating the list doesn't timeout -- (before the given number of microseconds). -- --
--   >>> enumerateTimeout (2 * 10^6) :: IO (Maybe [Bool])  -- two seconds
--   Just [False,True]
--   
enumerateTimeout :: (Enumerable a, NFData a) => Int -> IO (Maybe [a]) instance GHC.Enum.Bounded Data.Enumerate.Types.Jectivity instance GHC.Enum.Enum Data.Enumerate.Types.Jectivity instance GHC.Classes.Ord Data.Enumerate.Types.Jectivity instance GHC.Classes.Eq Data.Enumerate.Types.Jectivity instance GHC.Read.Read Data.Enumerate.Types.Jectivity instance GHC.Show.Show Data.Enumerate.Types.Jectivity instance Data.Enumerate.Types.GEnumerable GHC.Generics.V1 instance Data.Enumerate.Types.GEnumerable GHC.Generics.U1 instance Data.Enumerate.Types.Enumerable a => Data.Enumerate.Types.GEnumerable (GHC.Generics.K1 GHC.Generics.R a) instance (Data.Enumerate.Types.GEnumerable f, Data.Enumerate.Types.GEnumerable g) => Data.Enumerate.Types.GEnumerable (f GHC.Generics.:*: g) instance (Data.Enumerate.Types.GEnumerable f, Data.Enumerate.Types.GEnumerable g) => Data.Enumerate.Types.GEnumerable (f GHC.Generics.:+: g) instance Data.Enumerate.Types.GEnumerable f => Data.Enumerate.Types.GEnumerable (GHC.Generics.M1 GHC.Generics.S t f) instance Data.Enumerate.Types.GEnumerable f => Data.Enumerate.Types.GEnumerable (GHC.Generics.M1 GHC.Generics.C t f) instance Data.Enumerate.Types.GEnumerable f => Data.Enumerate.Types.GEnumerable (GHC.Generics.M1 GHC.Generics.D t f) instance (GHC.Enum.Bounded a, GHC.Enum.Enum a) => Data.Enumerate.Types.Enumerable (Data.Enumerate.Types.WrappedBoundedEnum a) instance Data.Enumerate.Types.Enumerable Data.Void.Void instance Data.Enumerate.Types.Enumerable () instance Data.Enumerate.Types.Enumerable GHC.Types.Bool instance Data.Enumerate.Types.Enumerable GHC.Types.Ordering instance Data.Enumerate.Types.Enumerable GHC.Int.Int8 instance Data.Enumerate.Types.Enumerable GHC.Word.Word8 instance Data.Enumerate.Types.Enumerable GHC.Int.Int16 instance Data.Enumerate.Types.Enumerable GHC.Word.Word16 instance Data.Enumerate.Types.Enumerable GHC.Types.Char instance (Data.Enumerate.Types.Enumerable a, Data.Enumerate.Types.Enumerable b) => Data.Enumerate.Types.Enumerable (Data.Either.Either a b) instance Data.Enumerate.Types.Enumerable a => Data.Enumerate.Types.Enumerable (GHC.Base.Maybe a) instance (Data.Enumerate.Types.Enumerable a, Data.Enumerate.Types.Enumerable b) => Data.Enumerate.Types.Enumerable (a, b) instance (Data.Enumerate.Types.Enumerable a, Data.Enumerate.Types.Enumerable b, Data.Enumerate.Types.Enumerable c) => Data.Enumerate.Types.Enumerable (a, b, c) instance (Data.Enumerate.Types.Enumerable a, Data.Enumerate.Types.Enumerable b, Data.Enumerate.Types.Enumerable c, Data.Enumerate.Types.Enumerable d) => Data.Enumerate.Types.Enumerable (a, b, c, d) instance (Data.Enumerate.Types.Enumerable a, Data.Enumerate.Types.Enumerable b, Data.Enumerate.Types.Enumerable c, Data.Enumerate.Types.Enumerable d, Data.Enumerate.Types.Enumerable e) => Data.Enumerate.Types.Enumerable (a, b, c, d, e) instance (Data.Enumerate.Types.Enumerable a, Data.Enumerate.Types.Enumerable b, Data.Enumerate.Types.Enumerable c, Data.Enumerate.Types.Enumerable d, Data.Enumerate.Types.Enumerable e, Data.Enumerate.Types.Enumerable f) => Data.Enumerate.Types.Enumerable (a, b, c, d, e, f) instance (Data.Enumerate.Types.Enumerable a, Data.Enumerate.Types.Enumerable b, Data.Enumerate.Types.Enumerable c, Data.Enumerate.Types.Enumerable d, Data.Enumerate.Types.Enumerable e, Data.Enumerate.Types.Enumerable f, Data.Enumerate.Types.Enumerable g) => Data.Enumerate.Types.Enumerable (a, b, c, d, e, f, g) instance (Data.Enumerate.Types.Enumerable (f a), Data.Enumerate.Types.Enumerable (Data.Vinyl.Core.Rec f as)) => Data.Enumerate.Types.Enumerable (Data.Vinyl.Core.Rec f (a : as)) instance Data.Enumerate.Types.Enumerable (Data.Vinyl.Core.Rec f '[]) instance (Data.Enumerate.Types.Enumerable a, GHC.Classes.Ord a) => Data.Enumerate.Types.Enumerable (Data.Set.Base.Set a) -- | see reifyFunctionAtM. -- --
--   -- doctest
--   
-- --
--   >>> :set +m
--   
module Data.Enumerate.Reify -- | reify a total function. -- --
--   >>> reifyFunction not
--   [(False,True),(True,False)]
--   
reifyFunction :: (Enumerable a) => (a -> b) -> [(a, b)] -- | reify a total function at any subset of the domain. reifyFunctionAt :: [a] -> (a -> b) -> [(a, b)] -- | reify a (safely-)partial function into a map (which is implicitly -- partial, where Map.lookup is like ($). reifyFunctionM :: (Enumerable a) => (forall m. MonadThrow m => a -> m b) -> [(a, b)] -- | reify a (safely-)partial function at any domain. -- -- use the functions suffixed with M when your function is -- explicitly partial, i.e. of type (forall m. MonadThrow m => a -- -> m b). when inside a function arrow, like: -- --
--   reifyFunctionAtM :: [a] -> (forall m. MonadThrow m => a -> m b) -> [(a,b)]
--   reifyFunctionAtM domain f = ... 
--   
-- -- the Rank2 type (and non-concrete types) means that f -- can only use parametric polymorphic functions, or the methods of the -- MonadThrow class (namely throwM), or methods of -- MonadThrow superclasses (namely return, et cetera). -- -- MonadThrow is a class from the exceptions package that -- generalizes failibility. it has instances for Maybe, -- Either, [], IO, and more. -- -- use the functions suffixed with At when your domain isn't -- Enumerable, or when you want to restrict the domain. -- -- the most general function in this module. -- --
--   >>> :{
--   let uppercasePartial :: (MonadThrow m) => Char -> m Char 
--       uppercasePartial c = case c of
--        'a' -> return 'A'
--        'b' -> return 'B'
--        'z' -> return 'Z'
--        _   -> failed "uppercasePartial"
--   :}
--   
-- --
--   >>> reifyFunctionAtM ['a'..'c'] uppercasePartial
--   [(a,A),(b,B)] 
--   
-- -- if your function doesn't fail under MonadThrow, see: -- -- reifyFunctionAtM :: [a] -> (Partial a b) -> [(a, b)] -- |
--   reifyPredicateAt = flip filter
--   
reifyPredicateAt :: [a] -> (a -> Bool) -> [a] -- | reify a (safely-)partial function that fails specifically under -- Maybe. reifyFunctionMaybeAt :: [a] -> (a -> Maybe b) -> [(a, b)] -- | reify a (safely-)partial function that fails specifically under -- []. reifyFunctionListAt :: [a] -> (a -> [b]) -> [(a, b)] -- | reify a (safely-)partial function that fails specifically under -- Either SomeException. reifyFunctionEitherAt :: [a] -> (a -> Either SomeException b) -> [(a, b)] -- | reifies an *unsafely*-partial function (i.e. a function that throws -- exceptions or that has inexhaustive pattern matching). -- -- forces the function to be strict. -- --
--   >>> import Data.Ratio (Ratio) 
--   >>> fmap (1/) [0..3 :: Ratio Integer]
--   [*** Exception: Ratio has zero denominator
--   >>> let (1/) = reciprocal 
--   >>> reifyFunctionSpoonAt [0..3 :: Ratio Integer] reciprocal 
--   [(1 % 1,1 % 1),(2 % 1,1 % 2),(3 % 1,1 % 3)]
--   
-- -- normal caveats from violating purity (via unsafePerformIO) -- and from catchalls (via (e :: SomeExceptions -> _)) apply. reifyFunctionSpoonAt :: (NFData b) => [a] -> (a -> b) -> [(a, b)] -- | reify a binary total function reifyFunction2 :: (Enumerable a, Enumerable b) => (a -> b -> c) -> [(a, [(b, c)])] -- | reify a binary total function at some domain reifyFunction2At :: [a] -> [b] -> (a -> b -> c) -> [(a, [(b, c)])] -- | reify a binary (safely-)partial function reifyFunction2M :: (Enumerable a, Enumerable b) => (forall m. MonadThrow m => a -> b -> m c) -> [(a, [(b, c)])] -- | reify a binary (safely-)partial function at some domain reifyFunction2AtM :: [a] -> [b] -> (forall m. MonadThrow m => a -> b -> m c) -> [(a, [(b, c)])] -- | converting between partial functions and maps. -- --
--   -- doctest
--   
-- --
--   >>> :set +m
--   
--   >>> :set -XLambdaCase
--   
--   >>> :{
--   let uppercasePartial :: (MonadThrow m) => Char -> m Char  -- Partial Char Char 
--       uppercasePartial = \case
--        'a' -> return 'A'
--        'b' -> return 'B'
--        'z' -> return 'Z'
--        _   -> failed "uppercasePartial"
--   :}
--   
-- -- a (safely-)partial function is isomorphic with a Map: -- --
--   fromFunctionM . toFunctionM = id 
--   toFunctionM . fromFunctionM = id
--   
-- -- modulo the error thrown. module Data.Enumerate.Map -- | convert a total function to a map. -- --
--   >>> fromFunction not 
--   fromList [(False,True),(True,False)]
--   
fromFunction :: (Enumerable a, Ord a) => (a -> b) -> Map a b -- | convert a (safely-)partial function to a map. -- -- wraps reifyFunctionM. fromFunctionM :: (Enumerable a, Ord a) => (Partial a b) -> Map a b -- | convert a map to a function, if the map is total. -- --
--   >>> let Just not' = toFunction (Map.fromList [(False,True),(True,False)])
--   >>> not' False 
--   True 
--   
toFunction :: (Enumerable a, Ord a) => Map a b -> Maybe (a -> b) -- | convert a (safely-)partial function to a map. -- -- lookup failures are throwMn as a PatternMatchFail. -- --
--   >>> let idPartial = toFunctionM (Map.fromList [(True,True)])
--   >>> idPartial True
--   True
--   >>> idPartial False 
--   *** Exception: toFunctionM
--   
toFunctionM :: (Enumerable a, Ord a) => Map a b -> (Partial a b) -- | wraps lookup unsafeToFunction :: (Ord a) => Map a b -> (a -> b) -- | does the map contain every key in its domain? -- --
--   >>> isMapTotal (Map.fromList [(False,True),(True,False)])
--   True 
--   
-- --
--   >>> isMapTotal (Map.fromList [('a',0)])
--   False 
--   
isMapTotal :: (Enumerable a, Ord a) => Map a b -> Bool -- | safely invert any map. invertMap :: (Ord a, Ord b) => Map a b -> Map b (NonEmpty a) -- | refines the partial function, if total. -- --
--   >>> :{
--   let myNotM :: Monad m => Bool -> m Bool
--       myNotM False = return True 
--       myNotM True  = return False 
--   :} 
--   
--   >>> let Just myNot = isTotalM myNotM
--   
--   >>> myNot False
--   True
--   
isTotalM :: (Enumerable a, Ord a) => (Partial a b) -> Maybe (a -> b) -- | the domain of a partial function is the subset of the -- enumerated input where it's defined. -- -- i.e. when x `member` (domainM f) then fromJust (f x) -- is defined. -- --
--   >>> domainM uppercasePartial
--   ['a','b','z'] 
--   
domainM :: (Enumerable a) => (Partial a b) -> [a] -- | (right name?) -- --
--   corange _ = enumerated
--   
corange :: (Enumerable a) => (a -> b) -> [a] -- |
--   corangeM _ = enumerated
--   
corangeM :: (Enumerable a) => (Partial a b) -> [a] -- | the image of a total function. -- --
--   imageM f = map f enumerated
--   
-- -- includes duplicates. image :: (Enumerable a) => (a -> b) -> [b] -- | the image (not the codomain) of a partial function. -- --
--   imageM f = mapMaybe f enumerated
--   
-- -- includes duplicates. imageM :: (Enumerable a) => (Partial a b) -> [b] -- | the codomain of a function. it contains the image. -- --
--   codomain _ = enumerated
--   
codomain :: (Enumerable b) => (a -> b) -> [b] codomainM :: (Enumerable b) => (Partial a b) -> [b] -- | invert a total function. -- -- (invert f) b is: -- -- -- --
--   invert f = invertM (return.f)
--   
invert :: (Enumerable a, Ord a, Ord b) => (a -> b) -> (b -> [a]) -- | invert a partial function. -- -- (invertM f) b is: -- -- -- -- a Map is stored internally, with as many keys as the -- image of f. -- -- see also isBijectiveM. invertM :: (Enumerable a, Ord a, Ord b) => (Partial a b) -> (b -> [a]) getJectivityM :: (Enumerable a, Enumerable b, Ord a, Ord b) => (Partial a b) -> Maybe Jectivity isInjective :: (Enumerable a, Ord a, Ord b) => (a -> b) -> Maybe (b -> Maybe a) -- | returns the inverse of the injection, if injective. -- -- refines (b -> [a]) (i.e. the type of invertM) to -- (b -> Maybe a). -- -- unlike isBijectiveM, doesn't need an (Enumerable b) -- constraint. this helps when you want to ensure a function into an -- infinite type (e.g. show) is injective. and still reasonably -- efficient, given the (Ord b) constraint. isInjectiveM :: (Enumerable a, Ord a, Ord b) => (Partial a b) -> Maybe (b -> Maybe a) -- | converts the list into a set, if it has no duplicates. isUnique :: (Ord a) => [a] -> Maybe (Set a) isSurjective :: (Enumerable a, Enumerable b, Ord a, Ord b) => (a -> b) -> Maybe (b -> NonEmpty a) -- | returns the inverse of the surjection, if surjective. i.e. when a -- function's codomainM equals its imageM. -- -- refines (b -> [a]) (i.e. the type of invertM) to -- (b -> NonEmpty a). -- -- can short-circuit. isSurjectiveM :: (Enumerable a, Enumerable b, Ord a, Ord b) => (Partial a b) -> Maybe (b -> NonEmpty a) isBijective :: (Enumerable a, Enumerable b, Ord a, Ord b) => (a -> b) -> Maybe (b -> a) -- | returns the inverse of the bijection, if bijective. -- -- refines (b -> [a]) (i.e. the type of invertM) to -- (b -> a). -- -- can short-circuit. isBijectiveM :: (Enumerable a, Enumerable b, Ord a, Ord b) => (Partial a b) -> Maybe (b -> a) -- | usage: -- --
--   data A = ...
--   
--   instance Bounded A where
--    minBound = minBound_enumerable array_A
--    maxBound = maxBound_enumerable array_A
--   
--   instance Enum A where
--    toEnum   = toEnum_enumerable   array_A
--    fromEnum = fromEnum_enumerable table_A
--   
--   -- CAF
--   array_A :: Array Int A
--   array_A = array_enumerable
--   
--   -- CAF
--   table_A :: Map A Int
--   table_A = table_enumerable
--   
--   -- we must pass in CAFs
--   -- (i.e. expressions that are top-level and unconstrained),
--   -- which will be shared between all calls to minBoundmaxBoundtoEnum/fromEnum.
--   -- TODO must we?
--   
-- -- -- -- (also see the source of Data.Enumerate.Example) module Data.Enumerate.Enum minBound_enumerable :: (Enumerable a) => Array Int a -> a maxBound_enumerable :: (Enumerable a) => Array Int a -> a toEnum_enumerable :: (Enumerable a) => Array Int a -> (Int -> a) fromEnum_enumerable :: (Enumerable a, Ord a) => Map a Int -> (a -> Int) array_enumerable :: (Enumerable a) => Array Int a table_enumerable :: (Enumerable a, Ord a) => Map a Int -- | orphan instances, of Enumerate, for large types (i.e. -- Word32 / Word64 / Int32 / Int64). -- -- (that are included for completeness, but not exported by default (i.e. -- by Data.Enumerate). you probably want build-time -- instance-resolution errors rather than probable runtime -- non-termination). module Data.Enumerate.Large -- | finite but too big. 2^64 is over a billion billion -- (1,000,000,000,000). -- -- e.g. reifyFunction (which takes time linear in the domain) on a -- function of type (:: Int -> Bool), even a lazy one, won't -- terminate anytime soon. instance Data.Enumerate.Types.Enumerable GHC.Int.Int32 instance Data.Enumerate.Types.Enumerable GHC.Word.Word32 instance Data.Enumerate.Types.Enumerable GHC.Int.Int64 instance Data.Enumerate.Types.Enumerable GHC.Word.Word64 -- | orphan instances, of 'Enumerate'\/'Eq'\/'Show', for functions. -- -- (that are included for completeness, but not exported by default (i.e. -- by Data.Enumerate). you probably want build-time -- instance-resolution errors rather than possible runtime -- non-termination). -- --
--   -- doctest
--   
-- --
--   >>> :set -XLambdaCase
--   
--   >>> let printMappings mappings = traverse (\mapping -> (putStrLn"") >> (traverse print) mapping) mappings >> return()
--   
module Data.Enumerate.Function -- | the exponential type. -- -- the cardinality is the cardinality of b raised to the -- cardinality a, i.e. |b|^|a|. -- -- warning: it grows very quickly. -- -- might be useful for generating random functions on small types, like -- to fuzz test type class laws. -- -- the cardinality call is efficient (depending on the efficiency -- of the base type's call). you should be able to safely (WRT -- performance) call enumerateBelow, unless the arithmetic itself -- becomes too expensive. -- --
--   instance (Enumerable a, Enumerable b, Ord a, Ord b) => Enumerable (a -> b) where 
--    enumerated = functionEnumerated
--   
-- | brute-force function extensionality. -- -- warning: the size of the domain grows exponentially in the number of -- arguments. -- --
--   >>> (\case LT -> False; EQ -> False; GT -> False) == const False
--   True
--   
--   >>> (\case LT -> False; EQ -> False; GT -> False) == const True
--   False
--   
-- -- because functions are curried, the instance is recursive, and it works -- on functions of any arity: -- --
--    -- De Morgan's laws
--   >> (\x y -> not (x && y)) == (\x y -> not x || not y)
--   
-- -- True >>> (x y -> not (x || y)) == (x y -> not x -- && not y) True -- |
--   >>> print not
--   unsafeFromList [(False,True),(True,False)]
--   
-- -- because functions are curried, the instance is recursive, and it works -- on functions of any arity: -- --
--   >>> print (&&)
--   unsafeFromList [(False,unsafeFromList [(False,False),(True,False)]),(True,unsafeFromList [(False,False),(True,True)])]
--   
-- | wraps lookup -- --
--   >>> (unsafeFromList [(False,True),(True,False)]) False
--   True
--   
--   >>> (unsafeFromList [(False,True),(True,False)]) True
--   False
--   
unsafeFromList :: (Ord a) => [(a, b)] -> (a -> b) -- | see mappingEnumeratedAt functionEnumerated :: (Enumerable a, Enumerable b, Ord a, Ord b) => [a -> b] -- | [(a,b)] is a mapping, [[(a,b)]] is a list of -- mappings. -- --
--   >>> let orderingPredicates = mappingEnumeratedAt [LT,EQ,GT] [False,True]
--   
--   >>> print $ length orderingPredicates
--   8
--   
--   >>> printMappings $ orderingPredicates
--   
--   (LT,False)
--   (EQ,False)
--   (GT,False)
--   
--   (LT,False)
--   (EQ,False)
--   (GT,True)
--   
--   (LT,False)
--   (EQ,True)
--   (GT,False)
--   
--   (LT,False)
--   (EQ,True)
--   (GT,True)
--   
--   (LT,True)
--   (EQ,False)
--   (GT,False)
--   
--   (LT,True)
--   (EQ,False)
--   (GT,True)
--   
--   (LT,True)
--   (EQ,True)
--   (GT,False)
--   
--   (LT,True)
--   (EQ,True)
--   (GT,True)
--   
--   (LT,False)
--   (EQ,False)
--   (GT,False)
--   
--   (LT,False)
--   (EQ,False)
--   (GT,True)
--   
--   (LT,False)
--   (EQ,True)
--   (GT,False)
--   
--   (LT,False)
--   (EQ,True)
--   (GT,True)
--   
--   (LT,True)
--   (EQ,False)
--   (GT,False)
--   
--   (LT,True)
--   (EQ,False)
--   (GT,True)
--   
--   (LT,True)
--   (EQ,True)
--   (GT,False)
--   
--   (LT,True)
--   (EQ,True)
--   (GT,True)
--   
-- -- where the (total) mapping: -- --
--   (LT,False)
--   (EQ,False)
--   (GT,True)
--   
-- -- is equivalent to the function: -- --
--   \case
--    LT -> False
--    EQ -> False
--    GT -> True
--   
mappingEnumeratedAt :: [a] -> [b] -> [[(a, b)]] -- |
--   >>> let crossOrderingBoolean = crossProduct [LT,EQ,GT] [False,True]
--   
--   >>> printMappings $ crossOrderingBoolean
--   
--   >>> 
--   (LT,False)
--   (LT,True)
--   
--   (EQ,False)
--   (EQ,True)
--   
--   (GT,False)
--   (GT,True)
--   
-- -- the length of the outer list is the size of the first set and the -- length of the inner list is the size of the second set. -- --
--   >>> print $ length crossOrderingBoolean
--   3
--   
--   >>> print $ length (head crossOrderingBoolean)
--   2
--   
crossProduct :: [a] -> [b] -> [[(a, b)]] instance (Data.Enumerate.Types.Enumerable a, Data.Enumerate.Types.Enumerable b, GHC.Classes.Ord a, GHC.Classes.Ord b) => Data.Enumerate.Types.Enumerable (a -> b) instance (Data.Enumerate.Types.Enumerable a, GHC.Classes.Eq b) => GHC.Classes.Eq (a -> b) instance (Data.Enumerate.Types.Enumerable a, GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (a -> b) -- | see Data.Enumerable.Types for detailed documentation. -- -- to import every symbol in this package, run this in GHCi: -- --
--   :m +  Data.Enumerate  Data.Enumerate.Extra  Data.Enumerate.Large  Data.Enumerate.Function
--   
-- -- the modules Data.Enumerate.Large and -- Data.Enumerate.Function have orphan instances for large types, -- and aren't reexported by default. this makes attempting to enumerate -- them a type error, rather than runtime non-termination. -- -- See the source of Data.Enumerate.Example for an example. module Data.Enumerate module Data.Enumerate.Example main :: IO () -- | (for documentation) -- -- demonstrates: empty type, unit type, product type, sum type, type -- variable. -- -- with {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}, the -- derivation is a one-liner: -- --
--   data Demo a = ... deriving (Show,Generic,Enumerable)
--   
data Demo a Demo0 :: Void -> Demo a Demo1 :: Demo a Demo2 :: Bool -> (Maybe Bool) -> Demo a Demo3 :: a -> Demo a -- | (for documentation) -- --
--   demoEnumerated = enumerated
--   
-- --
--   >>> traverse print demoEnumerated
--   Demo1
--   Demo2 False Nothing
--   Demo2 False (Just False)
--   Demo2 False (Just True)
--   Demo2 True Nothing
--   Demo2 True (Just False)
--   Demo2 True (Just True)
--   Demo3 False
--   Demo3 True
--   
demoEnumerated :: [Demo Bool] array_DemoBool :: Array Int (Demo Bool) table_DemoBool :: Map (Demo Bool) Int instance GHC.Generics.Constructor Data.Enumerate.Example.C1_3Demo instance GHC.Generics.Constructor Data.Enumerate.Example.C1_2Demo instance GHC.Generics.Constructor Data.Enumerate.Example.C1_1Demo instance GHC.Generics.Constructor Data.Enumerate.Example.C1_0Demo instance GHC.Generics.Datatype Data.Enumerate.Example.D1Demo instance Data.Enumerate.Types.Enumerable a => Data.Enumerate.Types.Enumerable (Data.Enumerate.Example.Demo a) instance GHC.Generics.Generic (Data.Enumerate.Example.Demo a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Enumerate.Example.Demo a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Enumerate.Example.Demo a) instance GHC.Show.Show a => GHC.Show.Show (Data.Enumerate.Example.Demo a) instance GHC.Enum.Bounded (Data.Enumerate.Example.Demo GHC.Types.Bool) instance GHC.Enum.Enum (Data.Enumerate.Example.Demo GHC.Types.Bool)