R      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~None!"#$/0123459:;<=?DKLOQRT[\a   failed =  . &generalize a function that fails with Nothing.&generalize a function that fails with [].&generalize a function that fails with Left.specialization specialization specialization 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). !handles the following exceptions: $Evaluate a value to normal form and H any exceptions are thrown during evaluation. For any error-free value,  spoon = Just.(taken from the  Ghttps://hackage.haskell.org/package/spoon-0.3.1/docs/Control-Spoon.htmlspoon package.);the eliminator as a function and the introducer as a stringThelper for declaring Show instances of datatypes without visible constructors (like Map which is shown as a list).    None !"#$/01234579:;<=?DKLOQRT[\a2a (safely-)partial function. i.e. a function that:fails only via the throwM method of succeeds only via the  method of ,see "Enumerate.Function.Reify.getJectivityM"None!"#$/0123459:;<=?DKLOQRT[\a reify a total function. # >>> reifyFunction not -- Prelude  [(False,True),(True,False)] !3reify a total function at any subset of the domain."Qreify a (safely-)partial function into a map (which is implicitly partial, where  Map.lookup is like ($).#0reify a (safely-)partial function at any domain. use the functions suffixed with M8 when your function is explicitly partial, i.e. of type $(forall m. MonadThrow m => a -> m b)%. when inside a function arrow, like: kreifyFunctionAtM :: [a] -> (forall m. MonadThrow m => a -> m b) -> [(a,b)] reifyFunctionAtM domain f = ... the Rank2* type (and non-concrete types) means that fF can only use parametric polymorphic functions, or the methods of the  MonadThrow class (namely ), or methods of  MonadThrow superclasses (namely  , et cetera). 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 *, or when you want to restrict the domain.)the most general function in this module.:{8let 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 , see:reifyFunctionAtMaybereifyFunctionAtListreifyFunctionAtEither$ reifyPredicateAt =  %@reify a (safely-)partial function that fails specifically under Maybe.&@reify a (safely-)partial function that fails specifically under [].'@reify a (safely-)partial function that fails specifically under Either SomeException.(zreifies 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 denominatorlet (1/) = reciprocal7reifyFunctionSpoonAt [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.)reify a binary total function*,reify a binary total function at some domain+(reify a binary (safely-)partial function,7reify a binary (safely-)partial function at some domain !"#$%&'()*+, !"#$%&'()*+, !"#$%&'()*+, !"#$%&'()*+,None!"#$/0123459:;<=?DKLOQRT[\a-"convert a total function to a map. !>>> fromFunction not -- Prelude ' fromList [(False,True),(True,False)] .-convert a (safely-)partial function to a map.wraps "./-does the map contain every key in its domain?5isMapTotal (Map.fromList [(False,True),(True,False)])True#isMapTotal (Map.fromList [('a',0)])False0safely invert any map.1the  =https://en.wikipedia.org/wiki/Partial_function#Basic_conceptsdomain, of a partial function is the subset of the  input where it's defined. i.e. when x `member` (domainM f) then fromJust (f x) is defined.domainM uppercasePartial ['a','b','z']2 (right name?) corange _ = enumerated3 corangeM _ = enumerated4the image of a total function. imageM f = map f includes duplicates.5the image (not the 6) of a partial function. imageM f = mapMaybe f includes duplicates.6,the codomain of a function. it contains the 4. codomain _ = enumerated8invert a total function. (invert f) b is:[] wherever f is not surjective[y] wherever f is uniquely defined(_:_) wherever f is not injective  invert f = 9 (return.f)9invert a partial function. (invertM f) b is:[] wherever f is partial[] wherever f is not surjective[y] wherever f is uniquely defined(_:_) wherever f is not injectivea Map0 is stored internally, with as many keys as the 4 of f. see also A.<3returns the inverse of the injection, if injective.refines  (b -> [a]) (i.e. the type of 9) to (b -> Maybe a).unlike A, doesn't need an (Enumerable b)W constraint. this helps when you want to ensure a function into an infinite type (e.g. :) is injective. and still reasonably efficient, given the (Ord b) constraint.=6converts the list into a set, if it has no duplicates.?Mreturns the inverse of the surjection, if surjective. i.e. when a function's 7 equals its 5.refines  (b -> [a]) (i.e. the type of 9) to (b -> NonEmpty a).can short-circuit.A3returns the inverse of the bijection, if bijective.refines  (b -> [a]) (i.e. the type of 9) to (b -> a).can short-circuit.-./0123456789:;<=>?@A-./0123456789:;<=>?@A-./0123456789:;<=>?@A-./0123456789:;<=>?@ANone!"#$/0123459:;<=?DKLOQRT[\a B1convert a map to a function, if the map is total.Glet (Just not_) = toFunction (Map.fromList [(False,True),(True,False)]) not_ FalseTrueC-convert a (safely-)partial function to a map.lookup failures are n as a .8let idPartial = toFunctionM (Map.fromList [(True,True)])idPartial TrueTrueidPartial False*** Exception: toFunctionMDwraps E'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 FalseTrueFwraps 2(unsafeFromList [(False,True),(True,False)]) FalseTrue1(unsafeFromList [(False,True),(True,False)]) TrueFalseGsee N H  |b| ^ |a|IFare all pairs of outputs the same for the same input? (short-ciruits).JEis any pair of outputs different for the same input? (short-ciruits).K&show all inputs and their outputs, as unsafeFromList [...].L&show all inputs and their outputs, as case ....N[(a,b)] is a mapping,  [[(a,b)]] is a list of mappings.Dlet orderingPredicates = mappingEnumeratedAt [LT,EQ,GT] [False,True]!print $ length orderingPredicates8"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)where the (total) mapping:  (LT,False) (EQ,False) (GT,True) is equivalent to the function: ,\case LT -> False EQ -> False GT -> True O?let crossOrderingBoolean = crossProduct [LT,EQ,GT] [False,True]$printMappings $ crossOrderingBoolean (LT,False) (LT,True) (EQ,False) (EQ,True) (GT,False) (GT,True)zthe 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 crossOrderingBoolean3*print $ length (head crossOrderingBoolean)2BCDEFGHIJKLMNOBCDEFGHIJKLMNOBCDEFGHIJKLMNOBCDEFGHIJKLMNONone !"#$,/0123459:;<=?DKLQRT[\aP - >>> not,- unsafeFromList [(False,True),(True,False)]abecause functions are curried, the instance is recursive, and it works on functions of any arity: - >>> (&&)x- unsafeFromList [(False,unsafeFromList [(False,False),(True,False)]),(True,unsafeFromList [(False,False),(True,True)])]Q$brute-force function extensionality.Owarning: the size of the domain grows exponentially in the number of arguments.<(\case LT -> False; EQ -> False; GT -> False) == const FalseTrue;(\case LT -> False; EQ -> False; GT -> False) == const TrueFalseabecause functions are curried, the instance is recursive, and it works on functions of any arity: J -- 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) TrueRthe exponential type.the  is the cardinality of b raised to the cardinality a, i.e. |b|^|a|.warning: it grows very quickly.bmight be useful for generating random functions on small types, like to fuzz test type class laws.the ~ call is efficient (depending on the efficiency of the base type's call). you should be able to safely (WRT performance) call 5, unless the arithmetic itself becomes too expensive.  instance ( a, Enumerable b, 6 a, Ord b) => Enumerable (a -> b) where enumerated = G PQRRQPPQRNone!"#$/0123459:;<=?DKLQRT[\a6 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNONone!"#$/01234579:;<=?DKLQRT[\aSTUVWXYZ[\]^_`abcdefgSTWUVXZY[\]^_`abcdefgb`a\]^_XYZ[TUVWScdefg STUVWXYZ[\]^_`abcdefg      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghiijklmnopqrstuvwxyz{|}~/enumerate-function-0.0.1-5QoArEgJQi6BcghU01ilk1Enumerate.Function.ExtraEnumerate.Function.TypesEnumerate.Function.ReifyEnumerate.Function.InvertEnumerate.Function.MapEnumerate.Orphans.FunctionEnumerate.Function.ExampleEnumerate.Functionnothing maybe2bool either2maybe either2boolfailed maybe2throw list2throw either2throw throw2maybe throw2either throw2listtotalizeFunctiondefaultPartialityHandlers spoonWith showsPrecWith-?>Partial Jectivity Injective Surjective Bijective$fShowJectivity$fReadJectivity $fEqJectivity$fOrdJectivity$fEnumJectivity$fBoundedJectivity $fIxJectivity$fGenericJectivity$fDataJectivity$fNFDataJectivity$fEnumerableJectivity reifyFunctionreifyFunctionAtreifyFunctionMreifyFunctionAtMreifyPredicateAtreifyFunctionMaybeAtreifyFunctionListAtreifyFunctionEitherAtreifyFunctionSpoonAtreifyFunction2reifyFunction2AtreifyFunction2MreifyFunction2AtM fromFunction fromFunctionM isMapTotal invertMapdomainMcorangecorangeMimageimageMcodomain codomainMinvertinvertM getJectivityM isInjective isInjectiveMisUnique isSurjective isSurjectiveM isBijective isBijectiveM toFunction toFunctionMunsafeToFunctionisTotalMunsafeFromListfunctionEnumeratedfunctionCardinalityextensionallyEqualextensionallyUnequalfunctionShowsPrecdisplayFunctiondisplayInjectivemappingEnumeratedAt crossProduct $fShow(->)$fEq(->)$fEnumerable(->) KeyBindingRegion CharacterTokenLineSliceWhole BackwardsForwardsActionCutDelete TransposeEditmain emacsEditemacsTranspose emacsSelectemacsBeginRegionemacsEndRegion $fShowAction $fReadAction $fEqAction $fOrdAction $fEnumAction$fBoundedAction$fGenericAction$fEnumerableAction $fShowSlice $fReadSlice $fEqSlice $fOrdSlice $fEnumSlice$fBoundedSlice$fGenericSlice$fEnumerableSlice $fShowRegion $fReadRegion $fEqRegion $fOrdRegion $fEnumRegion$fBoundedRegion$fGenericRegion$fEnumerableRegion $fShowEdit $fReadEdit$fEqEdit $fOrdEdit $fGenericEdit$fEnumerableEdit'exceptions-0.8.3-5OTPYzRazb4DJ75sPncYEhControl.Monad.CatchthrowMbaseGHC.IO.Exception userError GHC.ExceptionArithExceptionArrayException ErrorCallControl.Exception.BasePatternMatchFail Data.DataData GHC.GenericsGenericData.Semigroup SemigroupControl.Category>>><<< Data.Foldable traverse_ Data.OldList intercalate Data.Function&deepseq-1.4.2.0Control.DeepSeqdeepseqNFDatarnf MonadThrowGHC.BasereturnMonadghc-prim GHC.Classesnot&enumerate-0.2.2-GLNw96DavM81ig8hsrFpXPEnumerate.Types EnumerableflipGHC.Listfilter enumeratedGHC.Showshowcontainers-0.5.7.1 Data.Map.Baselookup cardinalityenumerateBelowOrd