This module provides the Sized class. Instances of this class are typically collection data types for infinite sets of values with a finite number of values of any given size.
A simple example is Control.Enumerable.Count that just counts the number of values of each size. Control.Enumerable.Values provides all values of a given size.
FEAT provides any value in the set much more efficiently.
A variant of <*> with the types of the arguments reversed. It differs from
flip(<*>) in that the effects are resolved in the order the arguments are
presented.
>>> some (putStr "la")lalalalalalalalala... * goes on forever *
Example1 expression
>>> some Nothingnothing
Example1 expression
>>> take 5 <$> some (Just 1)* hangs forever *
Note that this function can be used with Parsers based on
Applicatives. In that case some parser will attempt to
parse parser one or more times until it fails.
>>> many (putStr "la")lalalalalalalalala... * goes on forever *
Example1 expression
>>> many NothingJust []
Example1 expression
>>> take 5 <$> many (Just 1)* hangs forever *
Note that this function can be used with Parsers based on
Applicatives. In that case many parser will attempt to
parse parser zero or more times until it fails.
Instances28Alternative, …
AlternativeSeqDefined in containers-0.8 · Data.Sequence.Internal
AlternativeSTMDefined in ghc-internal-9.1401.0 · GHC.Internal.Conc.Sync
sequence computations and combine their results (<*> and liftA2).
A minimal complete definition must include implementations of pure
and of either <*> or liftA2. If it defines both, then they must behave
the same as their default definitions:
Some functors support an implementation of liftA2 that is more
efficient than the default one. In particular, if fmap is an
expensive operation, it is likely better to use liftA2 than to
fmap over the structure and then use <*>.
This became a typeclass method in 4.10.0.0. Prior to that, it was
a function defined in terms of <*> and fmap.
Sequence actions, discarding the value of the first argument.
Examples
If used in conjunction with the Applicative instance for Maybe,
you can chain Maybe computations, with a possible "early return"
in case of Nothing.
Example1 expression
>>> Just 2 *> Just 3Just 3
Example1 expression
>>> Nothing *> Just 3Nothing
Of course a more interesting use case would be to have effectful
computations instead of just returning pure values.
Example4 expressions
>>> import Data.Char>>> import GHC.Internal.Text.ParserCombinators.ReadP>>> let p = string "my name is " *> munch1 isAlpha <* eof>>> readP_to_S p "my name is Simon"[("Simon","")]
Replace all locations in the input with the same value.
The default definition is fmap . const, but this may be
overridden with a more efficient version.
Examples
Perform a computation with Maybe and replace the result with a
constant value if it is Just:
Example2 expressions
>>> 'a' <$ Just 2Just 'a'>>> 'a' <$ NothingNothing
Because we ignore the second type parameter to Const,
the Applicative instance, which has
(<*>) :: Monoid m => Const m (a -> b) -> Const m a -> Const m b
essentially turns into Monoid m => m -> m -> m, which is (<>)
A sized functor is an applicative functor extended with a notion of cost/size of contained values. This is useful for any type of bounded recursion over infinite sets, most notably for various kind of enumerations.
The intention is that every sized functor definition models a (usually) infinite set (technically a bag) with a finite number of values of any given size. As long as every cyclic (recursive) definition has at least one application of pay, this invariant is guaranteed.
The module Control.Enumerable provides sized functor definitions for a lot of data types, such that the size of a value is the number of constructor applications it contains. It also allows deriving these functors for any user defined data type (using Template Haskell).
Finite numeric types. fin n contains all non-negative numbers below n. This definition is flat, all integers have the same size.
Implementing this function efficiently will have a great impact on applications that use a lot of bounded numeric types (e.g. Int).
Same as fin but the size of values may differ.
By default, the size of an integer is the number of significant bits in its binary representation. In other words, 0 has size zero, the values for size k>0 in finBits n are in the interval
(2^(k-1),min (2^k-1) n).