-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | TODO -- -- TODO @package enumerate-function @version 0.0.0 module Enumerate.Function.Extra nothing :: (Monad m) => m () maybe2bool :: Maybe a -> Bool either2maybe :: Either e a -> Maybe a either2bool :: Either e a -> Bool -- |
-- 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: -- --
-- -- doctest ---- --
-- >>> :set +m --module Enumerate.Function.Reify -- | reify a total function. -- --
-- >>> reifyFunction not -- Prelude 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: -- --
-- 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)])] module Enumerate.Function.Invert -- | convert a total function to a map. -- --
-- >>> fromFunction not -- Prelude 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 -- | 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)
-- | 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: -- --
-- (for 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 Enumerate.Function.Map -- | 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) -- | 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)
-- | 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] -- |
-- |b| ^ |a| --functionCardinality :: forall a b proxy. (Enumerable a, Enumerable b) => proxy (a -> b) -> Natural -- | are all pairs of outputs the same for the same input? (short-ciruits). extensionallyEqual :: (Enumerable a, Eq b) => (a -> b) -> (a -> b) -> Bool -- | is any pair of outputs different for the same input? (short-ciruits). extensionallyUnequal :: (Enumerable a, Eq b) => (a -> b) -> (a -> b) -> Bool -- | show all inputs and their outputs, as unsafeFromList [...]. functionShowsPrec :: (Enumerable a, Show a, Show b) => Int -> (a -> b) -> ShowS -- | show all inputs and their outputs, as case .... displayFunction :: (Enumerable a, Show a, Show b) => (a -> b) -> String displayInjective :: (Enumerable a, Ord a, Ord b, Show a, Show b) => (a -> b) -> Maybe String -- | [(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) ---- -- 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)]] -- | orphan instances, of 'Enumerate'\/'Eq'\/'Show', for functions: -- --
instance (Enumerable a, Enumerable b, Ord a, Ord b) => -- Enumerable (a -> b)
instance (Enumerable a, Eq b) => Eq (a -> b)
instance (Enumerable a, Show a, Show b) => Show (a -> -- b)
-- -- doctest ---- --
-- >>> :set -XLambdaCase --module Enumerate.Orphans.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 -- |
-- data Edit = Edit Action Slice Region -- deriving (Show,Read,Eq,Ord,Generic,Enumerable) -- -- data Action -- = Transpose -- | Copy -- | Delete -- deriving (Show,Read,Eq,Ord,Enum,Bounded,Generic,Enumerable) -- -- data Slice -- = Whole -- | Backwards -- | Forwards -- deriving (Show,Read,Eq,Ord,Enum,Bounded,Generic,Enumerable) -- -- data Region -- = Character -- | Token -- | Line -- deriving (Show,Read,Eq,Ord,Enum,Bounded,Generic,Enumerable) ---- -- we can enumerate every possible editing action: -- --
-- > enumerated :: [Edit] ---- --
-- type KeyBinding = [String] -- emacsEdit :: Edit -> KeyBinding ---- -- the `enumerate-function` package can: -- --