Copyright | (c) The University of Glasgow 2001 |
---|---|

License | BSD-style (see the file libraries/base/LICENSE) |

Maintainer | libraries@haskell.org |

Stability | stable |

Portability | portable |

Safe Haskell | Trustworthy |

Language | Haskell2010 |

Functions associated with the tuple data types.

# Documentation

`Solo`

is the canonical lifted 1-tuple, just like `(,)`

is the canonical
lifted 2-tuple (pair) and `(,,)`

is the canonical lifted 3-tuple (triple).

The most important feature of `Solo`

is that it is possible to force its
"outside" (usually by pattern matching) without forcing its "inside",
because it is defined as a datatype rather than a newtype. One situation
where this can be useful is when writing a function to extract a value from
a data structure. Suppose you write an implementation of arrays and offer
only this function to index into them:

index :: Array a -> Int -> a

Now imagine that someone wants to extract a value from an array and store it in a lazy-valued finite map/dictionary:

`insert "hello" (arr ``index`

12) m

This can actually lead to a space leak. The value is not actually extracted from the array until that value (now buried in a map) is forced. That means the entire array may be kept live by just that value! Often, the solution is to use a strict map, or to force the value before storing it, but for some purposes that's undesirable.

One common solution is to include an indexing function that can produce its
result in an arbitrary `Applicative`

context:

indexA :: Applicative f => Array a -> Int -> f a

When using `indexA`

in a *pure* context, `Solo`

serves as a handy
`Applicative`

functor to hold the result. You could write a non-leaky
version of the above example thus:

`case arr ``indexA`

12 of
Solo a -> insert "hello" a m

While such simple extraction functions are the most common uses for unary tuples, they can also be useful for fine-grained control of strict-spined data structure traversals, and for unifying the implementations of lazy and strict mapping functions.

MkSolo a |

#### Instances

MonadFix Solo Source # |
| ||||

MonadZip Solo Source # |
| ||||

Foldable Solo Source # |
| ||||

Defined in Data.Foldable fold :: Monoid m => Solo m -> m Source # foldMap :: Monoid m => (a -> m) -> Solo a -> m Source # foldMap' :: Monoid m => (a -> m) -> Solo a -> m Source # foldr :: (a -> b -> b) -> b -> Solo a -> b Source # foldr' :: (a -> b -> b) -> b -> Solo a -> b Source # foldl :: (b -> a -> b) -> b -> Solo a -> b Source # foldl' :: (b -> a -> b) -> b -> Solo a -> b Source # foldr1 :: (a -> a -> a) -> Solo a -> a Source # foldl1 :: (a -> a -> a) -> Solo a -> a Source # toList :: Solo a -> [a] Source # null :: Solo a -> Bool Source # length :: Solo a -> Int Source # elem :: Eq a => a -> Solo a -> Bool Source # maximum :: Ord a => Solo a -> a Source # minimum :: Ord a => Solo a -> a Source # | |||||

Foldable1 Solo Source # |
| ||||

Defined in Data.Foldable1 fold1 :: Semigroup m => Solo m -> m Source # foldMap1 :: Semigroup m => (a -> m) -> Solo a -> m Source # foldMap1' :: Semigroup m => (a -> m) -> Solo a -> m Source # toNonEmpty :: Solo a -> NonEmpty a Source # maximum :: Ord a => Solo a -> a Source # minimum :: Ord a => Solo a -> a Source # foldrMap1 :: (a -> b) -> (a -> b -> b) -> Solo a -> b Source # foldlMap1' :: (a -> b) -> (b -> a -> b) -> Solo a -> b Source # foldlMap1 :: (a -> b) -> (b -> a -> b) -> Solo a -> b Source # foldrMap1' :: (a -> b) -> (a -> b -> b) -> Solo a -> b Source # | |||||

Eq1 Solo Source # |
| ||||

Ord1 Solo Source # |
| ||||

Defined in Data.Functor.Classes | |||||

Read1 Solo Source # |
| ||||

Defined in Data.Functor.Classes liftReadsPrec :: (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (Solo a) Source # liftReadList :: (Int -> ReadS a) -> ReadS [a] -> ReadS [Solo a] Source # liftReadPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec (Solo a) Source # liftReadListPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec [Solo a] Source # | |||||

Show1 Solo Source # |
| ||||

Traversable Solo Source # |
| ||||

Applicative Solo Source # |
| ||||

Functor Solo Source # |
| ||||

Monad Solo Source # |
| ||||

Generic1 Solo Source # | |||||

Defined in GHC.Generics
| |||||

Data a => Data (Solo a) Source # |
| ||||

Defined in Data.Data gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Solo a -> c (Solo a) Source # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Solo a) Source # toConstr :: Solo a -> Constr Source # dataTypeOf :: Solo a -> DataType Source # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Solo a)) Source # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Solo a)) Source # gmapT :: (forall b. Data b => b -> b) -> Solo a -> Solo a Source # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Solo a -> r Source # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Solo a -> r Source # gmapQ :: (forall d. Data d => d -> u) -> Solo a -> [u] Source # gmapQi :: Int -> (forall d. Data d => d -> u) -> Solo a -> u Source # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Solo a -> m (Solo a) Source # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Solo a -> m (Solo a) Source # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Solo a -> m (Solo a) Source # | |||||

Monoid a => Monoid (Solo a) Source # |
| ||||

Semigroup a => Semigroup (Solo a) Source # |
| ||||

Bounded a => Bounded (Solo a) Source # | |||||

Enum a => Enum (Solo a) Source # | |||||

Defined in GHC.Enum succ :: Solo a -> Solo a Source # pred :: Solo a -> Solo a Source # toEnum :: Int -> Solo a Source # fromEnum :: Solo a -> Int Source # enumFrom :: Solo a -> [Solo a] Source # enumFromThen :: Solo a -> Solo a -> [Solo a] Source # enumFromTo :: Solo a -> Solo a -> [Solo a] Source # enumFromThenTo :: Solo a -> Solo a -> Solo a -> [Solo a] Source # | |||||

Generic (Solo a) Source # | |||||

Defined in GHC.Generics
| |||||

Ix a => Ix (Solo a) Source # | |||||

Read a => Read (Solo a) Source # |
| ||||

Show a => Show (Solo a) Source # |
| ||||

Eq a => Eq (Solo a) | |||||

Ord a => Ord (Solo a) | |||||

Defined in GHC.Classes | |||||

type Rep1 Solo Source # |
| ||||

Defined in GHC.Generics | |||||

type Rep (Solo a) Source # |
| ||||

Defined in GHC.Generics |

getSolo :: Solo a -> a Source #

Extract the value from a `Solo`

. Very often, values should be extracted
directly using pattern matching, to control just what gets evaluated when.
`getSolo`

is for convenience in situations where that is not the case:

When the result is passed to a *strict* function, it makes no difference
whether the pattern matching is done on the "outside" or on the
"inside":

Data.Set.insert (getSolo sol) set === case sol of Solo v -> Data.Set.insert v set

A traversal may be performed in `Solo`

in order to control evaluation
internally, while using `getSolo`

to extract the final result. A strict
mapping function, for example, could be defined

map' :: Traversable t => (a -> b) -> t a -> t b map' f = getSolo . traverse ((Solo $!) . f)