-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Strict data types and String IO. -- -- This package provides strict versions of some standard Haskell data -- types (pairs, Maybe and Either). It also contains strict IO -- operations. -- -- It is common knowledge that lazy datastructures can lead to -- space-leaks. This problem is particularly prominent, when using lazy -- datastructures to store the state of a long-running application in -- memory. One common solution to this problem is to use seq and -- its variants in every piece of code that updates your state. However a -- much easier solution is to use fully strict types to store such state -- values. By "fully strict types" we mean types for whose values it -- holds that, if they are in weak-head normal form, then they are also -- in normal form. Intuitively, this means that values of fully strict -- types cannot contain unevaluated thunks. -- -- To define a fully strict datatype, one typically uses the following -- recipe. -- --
    --
  1. Make all fields of every constructor strict; i.e., add a bang to -- all fields.
  2. --
  3. Use only strict types for the fields of the constructors.
  4. --
-- -- The second requirement is problematic as it rules out the use of the -- standard Haskell Maybe, Either, and pair types. This -- library solves this problem by providing strict variants of these -- types and their corresponding standard support functions and -- type-class instances. -- -- Note that this library does currently not provide fully strict lists. -- They can be added if they are really required. However, in many cases -- one probably wants to use unboxed or strict boxed vectors from the -- vector library -- (http://hackage.haskell.org/package/vector) instead of strict -- lists. Moreover, instead of Strings one probably wants to use -- strict Text values from the text library -- (http://hackage.haskell.org/package/text). -- -- This library comes with batteries included; i.e., mirror functions and -- instances of the lazy versions in base. It also includes -- instances for type-classes from the deepseq, binary, -- and hashable packages. @package strict @version 0.5 -- | The strict variant of the standard Haskell Either type and the -- corresponding variants of the functions from Data.Either. -- -- Note that the strict Either type is not an applicative functor, -- and therefore also no monad. The reasons are the same as the ones for -- the strict Maybe type, which are explained in -- Data.Maybe.Strict. module Data.Strict.Either -- | The strict choice type. data Either a b Left :: !a -> Either a b Right :: !b -> Either a b -- | Case analysis: if the value is Left a, apply the first -- function to a; if it is Right b, apply the -- second function to b. either :: (a -> c) -> (b -> c) -> Either a b -> c -- | Yields True iff the argument is of the form Left _. isLeft :: Either a b -> Bool -- | Yields True iff the argument is of the form Right _. isRight :: Either a b -> Bool -- | Extracts the element out of a Left and throws an error if the -- argument is a Right. fromLeft :: Either a b -> a -- | Extracts the element out of a Right and throws an error if the -- argument is a Left. fromRight :: Either a b -> b -- | Analogous to lefts in Data.Either. lefts :: [Either a b] -> [a] -- | Analogous to rights in Data.Either. rights :: [Either a b] -> [b] -- | Analogous to partitionEithers in Data.Either. partitionEithers :: [Either a b] -> ([a], [b]) instance GHC.Generics.Generic1 (Data.Strict.Either.Either a) instance GHC.Generics.Generic (Data.Strict.Either.Either a b) instance (Data.Data.Data a, Data.Data.Data b) => Data.Data.Data (Data.Strict.Either.Either a b) instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.Strict.Either.Either a b) instance (GHC.Read.Read a, GHC.Read.Read b) => GHC.Read.Read (Data.Strict.Either.Either a b) instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.Strict.Either.Either a b) instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Strict.Either.Either a b) instance GHC.Base.Functor (Data.Strict.Either.Either a) instance Data.Foldable.Foldable (Data.Strict.Either.Either e) instance Data.Traversable.Traversable (Data.Strict.Either.Either e) instance GHC.Base.Semigroup (Data.Strict.Either.Either a b) instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData b) => Control.DeepSeq.NFData (Data.Strict.Either.Either a b) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData1 (Data.Strict.Either.Either a) instance Control.DeepSeq.NFData2 Data.Strict.Either.Either instance (Data.Binary.Class.Binary a, Data.Binary.Class.Binary b) => Data.Binary.Class.Binary (Data.Strict.Either.Either a b) instance Data.Bifunctor.Bifunctor Data.Strict.Either.Either instance Data.Bifoldable.Bifoldable Data.Strict.Either.Either instance Data.Bitraversable.Bitraversable Data.Strict.Either.Either instance (Data.Hashable.Class.Hashable a, Data.Hashable.Class.Hashable b) => Data.Hashable.Class.Hashable (Data.Strict.Either.Either a b) instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable1 (Data.Strict.Either.Either a) instance Data.Hashable.Class.Hashable2 Data.Strict.Either.Either instance Data.Bifunctor.Assoc.Assoc Data.Strict.Either.Either instance Data.Bifunctor.Swap.Swap Data.Strict.Either.Either instance Data.Functor.Classes.Eq2 Data.Strict.Either.Either instance GHC.Classes.Eq a => Data.Functor.Classes.Eq1 (Data.Strict.Either.Either a) instance Data.Functor.Classes.Ord2 Data.Strict.Either.Either instance GHC.Classes.Ord a => Data.Functor.Classes.Ord1 (Data.Strict.Either.Either a) instance GHC.Show.Show a => Data.Functor.Classes.Show1 (Data.Strict.Either.Either a) instance Data.Functor.Classes.Show2 Data.Strict.Either.Either instance Data.Functor.Classes.Read2 Data.Strict.Either.Either instance GHC.Read.Read a => Data.Functor.Classes.Read1 (Data.Strict.Either.Either a) -- | The strict variant of the standard Haskell Maybe type and the -- corresponding variants of the functions from Data.Maybe. -- -- Note that in contrast to the standard lazy Maybe type, the -- strict Maybe type is not an applicative functor, and therefore -- also not a monad. The problem is the homomorphism law, which -- states that -- --
--   pure f <*> pure x = pure (f x)  -- must hold for all f
--   
-- -- This law does not hold for the expected applicative functor instance -- of Maybe, as this instance does not satisfy pure f -- <*> pure _|_ = pure (f _|_) for f = const. module Data.Strict.Maybe -- | The type of strict optional values. data Maybe a Nothing :: Maybe a Just :: !a -> Maybe a -- | Yields True iff the argument is of the form Just _. isJust :: Maybe a -> Bool -- | Yields True iff the argument is Nothing. isNothing :: Maybe a -> Bool -- | Extracts the element out of a Just and throws an error if the -- argument is Nothing. fromJust :: Maybe a -> a -- | Given a default value and a Maybe, yield the default value if -- the Maybe argument is Nothing and extract the value out -- of the Just otherwise. fromMaybe :: a -> Maybe a -> a -- | Given a default value, a function and a Maybe value, yields the -- default value if the Maybe value is Nothing and applies -- the function to the value stored in the Just otherwise. maybe :: b -> (a -> b) -> Maybe a -> b -- | Analogous to listToMaybe in Data.Maybe. listToMaybe :: [a] -> Maybe a -- | Analogous to maybeToList in Data.Maybe. maybeToList :: Maybe a -> [a] -- | Analogous to catMaybes in Data.Maybe. catMaybes :: [Maybe a] -> [a] -- | Analogous to mapMaybe in Data.Maybe. mapMaybe :: (a -> Maybe b) -> [a] -> [b] instance GHC.Generics.Generic1 Data.Strict.Maybe.Maybe instance GHC.Generics.Generic (Data.Strict.Maybe.Maybe a) instance Data.Data.Data a => Data.Data.Data (Data.Strict.Maybe.Maybe a) instance GHC.Show.Show a => GHC.Show.Show (Data.Strict.Maybe.Maybe a) instance GHC.Read.Read a => GHC.Read.Read (Data.Strict.Maybe.Maybe a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Strict.Maybe.Maybe a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Strict.Maybe.Maybe a) instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Strict.Maybe.Maybe a) instance GHC.Base.Semigroup a => GHC.Base.Monoid (Data.Strict.Maybe.Maybe a) instance GHC.Base.Functor Data.Strict.Maybe.Maybe instance Data.Foldable.Foldable Data.Strict.Maybe.Maybe instance Data.Traversable.Traversable Data.Strict.Maybe.Maybe instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Strict.Maybe.Maybe a) instance Control.DeepSeq.NFData1 Data.Strict.Maybe.Maybe instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Data.Strict.Maybe.Maybe a) instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Data.Strict.Maybe.Maybe a) instance Data.Hashable.Class.Hashable1 Data.Strict.Maybe.Maybe instance Data.Functor.Classes.Eq1 Data.Strict.Maybe.Maybe instance Data.Functor.Classes.Ord1 Data.Strict.Maybe.Maybe instance Data.Functor.Classes.Show1 Data.Strict.Maybe.Maybe instance Data.Functor.Classes.Read1 Data.Strict.Maybe.Maybe module Data.Strict.These -- | The strict these type. data These a b This :: !a -> These a b That :: !b -> These a b These :: !a -> !b -> These a b -- | Case analysis for the These type. these :: (a -> c) -> (b -> c) -> (a -> b -> c) -> These a b -> c -- | Takes two default values and produces a tuple. fromThese :: a -> b -> These a b -> (a, b) -- | Coalesce with the provided operation. mergeThese :: (a -> a -> a) -> These a a -> a -- | bimap and coalesce results with the provided operation. mergeTheseWith :: (a -> c) -> (b -> c) -> (c -> c -> c) -> These a b -> c -- | Select each constructor and partition them into separate lists. partitionThese :: [These a b] -> ([a], [b], [(a, b)]) -- | Select here and there elements and partition them -- into separate lists. partitionHereThere :: [These a b] -> ([a], [b]) -- | Like partitionEithers but for NonEmpty types. -- -- -- -- Note: this is not online algorithm. In the worst case it will -- traverse the whole list before deciding the result constructor. -- --
--   >>> partitionEithersNE $ Left 'x' :| [Right 'y']
--   These ('x' :| "") ('y' :| "")
--   
-- --
--   >>> partitionEithersNE $ Left 'x' :| map Left "yz"
--   This ('x' :| "yz")
--   
partitionEithersNE :: NonEmpty (Either a b) -> These (NonEmpty a) (NonEmpty b) distrThesePair :: These (a, b) c -> (These a c, These b c) undistrThesePair :: (These a c, These b c) -> These (a, b) c distrPairThese :: (These a b, c) -> These (a, c) (b, c) undistrPairThese :: These (a, c) (b, c) -> (These a b, c) instance GHC.Generics.Generic1 (Data.Strict.These.These a) instance GHC.Generics.Generic (Data.Strict.These.These a b) instance (Data.Data.Data a, Data.Data.Data b) => Data.Data.Data (Data.Strict.These.These a b) instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.Strict.These.These a b) instance (GHC.Read.Read a, GHC.Read.Read b) => GHC.Read.Read (Data.Strict.These.These a b) instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.Strict.These.These a b) instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Strict.These.These a b) instance (GHC.Base.Semigroup a, GHC.Base.Semigroup b) => GHC.Base.Semigroup (Data.Strict.These.These a b) instance GHC.Base.Functor (Data.Strict.These.These a) instance Data.Foldable.Foldable (Data.Strict.These.These a) instance Data.Traversable.Traversable (Data.Strict.These.These a) instance Data.Bifunctor.Bifunctor Data.Strict.These.These instance Data.Bifoldable.Bifoldable Data.Strict.These.These instance Data.Bitraversable.Bitraversable Data.Strict.These.These instance GHC.Base.Semigroup a => GHC.Base.Applicative (Data.Strict.These.These a) instance GHC.Base.Semigroup a => GHC.Base.Monad (Data.Strict.These.These a) instance Data.Functor.Classes.Eq2 Data.Strict.These.These instance GHC.Classes.Eq a => Data.Functor.Classes.Eq1 (Data.Strict.These.These a) instance Data.Functor.Classes.Ord2 Data.Strict.These.These instance GHC.Classes.Ord a => Data.Functor.Classes.Ord1 (Data.Strict.These.These a) instance GHC.Show.Show a => Data.Functor.Classes.Show1 (Data.Strict.These.These a) instance Data.Functor.Classes.Show2 Data.Strict.These.These instance Data.Functor.Classes.Read2 Data.Strict.These.These instance GHC.Read.Read a => Data.Functor.Classes.Read1 (Data.Strict.These.These a) instance Data.Bifunctor.Swap.Swap Data.Strict.These.These instance Data.Bifunctor.Assoc.Assoc Data.Strict.These.These instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData b) => Control.DeepSeq.NFData (Data.Strict.These.These a b) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData1 (Data.Strict.These.These a) instance Control.DeepSeq.NFData2 Data.Strict.These.These instance (Data.Binary.Class.Binary a, Data.Binary.Class.Binary b) => Data.Binary.Class.Binary (Data.Strict.These.These a b) instance (Data.Hashable.Class.Hashable a, Data.Hashable.Class.Hashable b) => Data.Hashable.Class.Hashable (Data.Strict.These.These a b) instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable1 (Data.Strict.These.These a) instance Data.Hashable.Class.Hashable2 Data.Strict.These.These -- | The strict variant of the standard Haskell pairs and the corresponding -- variants of the functions from Data.Tuple. -- -- Note that unlike regular Haskell pairs, (x :!: _|_) = (_|_ :!: y) -- = _|_ module Data.Strict.Tuple -- | The type of strict pairs. data Pair a b (:!:) :: !a -> !b -> Pair a b infix 2 :!: type (:!:) = Pair infix 2 :!: -- | Extract the first component of a strict pair. fst :: Pair a b -> a -- | Extract the second component of a strict pair. snd :: Pair a b -> b -- | Curry a function on strict pairs. curry :: (Pair a b -> c) -> a -> b -> c -- | Convert a curried function to a function on strict pairs. uncurry :: (a -> b -> c) -> Pair a b -> c -- | Analogous to swap from Data.Tuple swap :: Pair a b -> Pair b a -- | Zip for strict pairs (defined with zipWith). zip :: [a] -> [b] -> [Pair a b] -- | Unzip for stict pairs into a (lazy) pair of lists. unzip :: [Pair a b] -> ([a], [b]) instance GHC.Generics.Generic1 (Data.Strict.Tuple.Pair a) instance (GHC.Ix.Ix a, GHC.Ix.Ix b) => GHC.Ix.Ix (Data.Strict.Tuple.Pair a b) instance (GHC.Enum.Bounded a, GHC.Enum.Bounded b) => GHC.Enum.Bounded (Data.Strict.Tuple.Pair a b) instance GHC.Generics.Generic (Data.Strict.Tuple.Pair a b) instance (Data.Data.Data a, Data.Data.Data b) => Data.Data.Data (Data.Strict.Tuple.Pair a b) instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.Strict.Tuple.Pair a b) instance (GHC.Read.Read a, GHC.Read.Read b) => GHC.Read.Read (Data.Strict.Tuple.Pair a b) instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.Strict.Tuple.Pair a b) instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Strict.Tuple.Pair a b) instance GHC.Base.Functor (Data.Strict.Tuple.Pair e) instance Data.Foldable.Foldable (Data.Strict.Tuple.Pair e) instance Data.Traversable.Traversable (Data.Strict.Tuple.Pair e) instance (GHC.Base.Semigroup a, GHC.Base.Semigroup b) => GHC.Base.Semigroup (Data.Strict.Tuple.Pair a b) instance (GHC.Base.Monoid a, GHC.Base.Monoid b) => GHC.Base.Monoid (Data.Strict.Tuple.Pair a b) instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData b) => Control.DeepSeq.NFData (Data.Strict.Tuple.Pair a b) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData1 (Data.Strict.Tuple.Pair a) instance Control.DeepSeq.NFData2 Data.Strict.Tuple.Pair instance (Data.Binary.Class.Binary a, Data.Binary.Class.Binary b) => Data.Binary.Class.Binary (Data.Strict.Tuple.Pair a b) instance Data.Bifunctor.Bifunctor Data.Strict.Tuple.Pair instance Data.Bifoldable.Bifoldable Data.Strict.Tuple.Pair instance Data.Bitraversable.Bitraversable Data.Strict.Tuple.Pair instance (Data.Hashable.Class.Hashable a, Data.Hashable.Class.Hashable b) => Data.Hashable.Class.Hashable (Data.Strict.Tuple.Pair a b) instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable1 (Data.Strict.Tuple.Pair a) instance Data.Hashable.Class.Hashable2 Data.Strict.Tuple.Pair instance Data.Bifunctor.Assoc.Assoc Data.Strict.Tuple.Pair instance Data.Bifunctor.Swap.Swap Data.Strict.Tuple.Pair instance Data.Functor.Classes.Eq2 Data.Strict.Tuple.Pair instance GHC.Classes.Eq a => Data.Functor.Classes.Eq1 (Data.Strict.Tuple.Pair a) instance Data.Functor.Classes.Ord2 Data.Strict.Tuple.Pair instance GHC.Classes.Ord a => Data.Functor.Classes.Ord1 (Data.Strict.Tuple.Pair a) instance GHC.Show.Show a => Data.Functor.Classes.Show1 (Data.Strict.Tuple.Pair a) instance Data.Functor.Classes.Show2 Data.Strict.Tuple.Pair instance Data.Functor.Classes.Read2 Data.Strict.Tuple.Pair instance GHC.Read.Read a => Data.Functor.Classes.Read1 (Data.Strict.Tuple.Pair a) module Data.Strict.Classes -- | Ad hoc conversion between "strict" and "lazy" versions of a structure. -- -- Unfortunately all externally defined instances are doomed to be -- orphans: https://gitlab.haskell.org/ghc/ghc/-/issues/11999 See -- also https://qfpl.io/posts/orphans-and-fundeps/index.html for class Strict lazy strict | lazy -> strict, strict -> lazy toStrict :: Strict lazy strict => lazy -> strict toLazy :: Strict lazy strict => strict -> lazy instance Data.Strict.Classes.Strict (GHC.Maybe.Maybe a) (Data.Strict.Maybe.Maybe a) instance Data.Strict.Classes.Strict (a, b) (Data.Strict.Tuple.Pair a b) instance Data.Strict.Classes.Strict (Data.Either.Either a b) (Data.Strict.Either.Either a b) instance Data.Strict.Classes.Strict (Data.These.These a b) (Data.Strict.These.These a b) instance Data.Strict.Classes.Strict Data.ByteString.Lazy.Internal.ByteString Data.ByteString.Internal.ByteString instance Data.Strict.Classes.Strict Data.Text.Internal.Lazy.Text Data.Text.Internal.Text instance Data.Strict.Classes.Strict (Control.Monad.ST.Lazy.Imp.ST s a) (GHC.ST.ST s a) instance Data.Strict.Classes.Strict (Control.Monad.Trans.RWS.Lazy.RWST r w s m a) (Control.Monad.Trans.RWS.Strict.RWST r w s m a) instance Data.Strict.Classes.Strict (Control.Monad.Trans.State.Lazy.StateT s m a) (Control.Monad.Trans.State.Strict.StateT s m a) instance Data.Strict.Classes.Strict (Control.Monad.Trans.Writer.Lazy.WriterT w m a) (Control.Monad.Trans.Writer.Strict.WriterT w m a) -- | Strict versions of some standard Haskell types. module Data.Strict -- | The standard IO input functions using strict IO. module System.IO.Strict -- | Computation hGetContents hdl returns the list of -- characters corresponding to the unread portion of the channel or file -- managed by hdl, which is immediate closed. -- -- Items are read strictly from the input Handle. -- -- This operation may fail with: -- -- hGetContents :: Handle -> IO String -- | The getContents operation returns all user input as a single -- string, which is read stirctly (same as hGetContents -- stdin). getContents :: IO String -- | The readFile function reads a file and returns the contents of -- the file as a string. The file is read strictly, as with -- getContents. readFile :: FilePath -> IO String -- | The interact function takes a function of type -- String->String as its argument. The entire input from the -- standard input device is passed to this function as its argument, and -- the resulting string is output on the standard output device. interact :: (String -> String) -> IO ()