-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A general abstraction for manipulating elements of container data structures
--   
--   An API for construction of free-form strategies of access and
--   manipulation of elements of arbitrary data structures. It allows to
--   implement efficient composite patterns, e.g., a simultaneous update
--   and lookup of an element, and even more complex things.
--   
--   Strategies are meant to be interpreted by the host data structure
--   libraries. Thus they allow to implement all access and modification
--   patterns of a data structure with just a single function, which
--   interprets strategies.
--   
--   This library provides pure and monadic interfaces, so it supports both
--   immutable and mutable data structures.
@package focus
@version 1.0.1.2

module Focus

-- | Abstraction over the modification of an element of a datastructure.
--   
--   It is composable using the standard typeclasses, e.g.:
--   
--   <pre>
--   lookupAndDelete :: Monad m =&gt; Focus a m (Maybe a)
--   lookupAndDelete = lookup &lt;* delete
--   </pre>
data Focus element m result
Focus :: m (result, Change element) -> (element -> m (result, Change element)) -> Focus element m result

-- | What to do with the focused value.
--   
--   The interpretation of the commands is up to the context APIs.
data Change a

-- | Produce no changes
Leave :: Change a

-- | Delete it
Remove :: Change a

-- | Set its value to the provided one
Set :: a -> Change a

-- | Reproduces the behaviour of <tt>Data.Map.<a>lookup</a></tt>.
member :: Monad m => Focus a m Bool

-- | Reproduces the behaviour of <tt>Data.Map.<a>lookup</a></tt>.
lookup :: Monad m => Focus a m (Maybe a)

-- | Reproduces the behaviour of <tt>Data.Map.<a>findWithDefault</a></tt>
--   with a better name.
lookupWithDefault :: Monad m => a -> Focus a m a

-- | Reproduces the behaviour of <tt>Data.Map.<a>delete</a></tt>.
delete :: Monad m => Focus a m ()

-- | Lookup an element and delete it if it exists.
--   
--   Same as <tt><a>lookup</a> &lt;* <a>delete</a></tt>.
lookupAndDelete :: Monad m => Focus a m (Maybe a)

-- | Reproduces the behaviour of <tt>Data.Map.<a>insert</a></tt>.
insert :: Monad m => a -> Focus a m ()

-- | Reproduces the behaviour of <tt>Data.Map.<a>insertWith</a></tt> with a
--   better name.
insertOrMerge :: Monad m => (a -> a -> a) -> a -> Focus a m ()

-- | Reproduces the behaviour of <tt>Data.Map.<a>alter</a></tt>.
alter :: Monad m => (Maybe a -> Maybe a) -> Focus a m ()

-- | Reproduces the behaviour of <tt>Data.Map.<a>adjust</a></tt>.
adjust :: Monad m => (a -> a) -> Focus a m ()

-- | Reproduces the behaviour of <tt>Data.Map.<a>update</a></tt>.
update :: Monad m => (a -> Maybe a) -> Focus a m ()

-- | Lift pure functions which handle the cases of presence and absence of
--   the element.
cases :: Monad m => (b, Change a) -> (a -> (b, Change a)) -> Focus a m b

-- | Lift pure functions which handle the cases of presence and absence of
--   the element and produce no result.
unitCases :: Monad m => Change a -> (a -> Change a) -> Focus a m ()

-- | A monadic version of <a>lookupWithDefault</a>.
lookupWithDefaultM :: Monad m => m a -> Focus a m a

-- | A monadic version of <a>insert</a>.
insertM :: Monad m => m a -> Focus a m ()

-- | A monadic version of <a>insertOrMerge</a>.
insertOrMergeM :: Monad m => (a -> a -> m a) -> m a -> Focus a m ()

-- | A monadic version of <a>alter</a>.
alterM :: Monad m => (Maybe a -> m (Maybe a)) -> Focus a m ()

-- | A monadic version of <a>adjust</a>.
adjustM :: Monad m => (a -> m a) -> Focus a m ()

-- | A monadic version of <a>update</a>.
updateM :: Monad m => (a -> m (Maybe a)) -> Focus a m ()

-- | Lift monadic functions which handle the cases of presence and absence
--   of the element.
casesM :: Monad m => m (b, Change a) -> (a -> m (b, Change a)) -> Focus a m b

-- | Lift monadic functions which handle the cases of presence and absence
--   of the element and produce no result.
unitCasesM :: Monad m => m (Change a) -> (a -> m (Change a)) -> Focus a m ()

-- | Map the Focus input.
mappingInput :: Monad m => (a -> b) -> (b -> a) -> Focus a m x -> Focus b m x

-- | Extends the output with the input.
extractingInput :: Monad m => Focus a m b -> Focus a m (b, Maybe a)

-- | Extends the output with the change performed.
extractingChange :: Monad m => Focus a m b -> Focus a m (b, Change a)

-- | Extends the output with a projection on the change that was performed.
projectingChange :: Monad m => (Change a -> c) -> Focus a m b -> Focus a m (b, c)

-- | Extends the output with a flag, signaling whether a change, which is
--   not <a>Leave</a>, has been introduced.
testingIfModifies :: Monad m => Focus a m b -> Focus a m (b, Bool)

-- | Extends the output with a flag, signaling whether the <a>Remove</a>
--   change has been introduced.
testingIfRemoves :: Monad m => Focus a m b -> Focus a m (b, Bool)

-- | Extends the output with a flag, signaling whether an item will be
--   inserted. That is, it didn't exist before and a <a>Set</a> change is
--   introduced.
testingIfInserts :: Monad m => Focus a m b -> Focus a m (b, Bool)

-- | Extend the output with a flag, signaling how the size will be affected
--   by the change.
testingSizeChange :: Monad m => sizeChange -> sizeChange -> sizeChange -> Focus a m b -> Focus a m (b, sizeChange)

-- | Focus on the contents of a TVar.
onTVarValue :: Focus a STM b -> Focus (TVar a) STM b
instance GHC.Show.Show a => GHC.Show.Show (Focus.Change a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Focus.Change a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Focus.Change a)
instance GHC.Base.Functor Focus.Change
instance GHC.Base.Functor m => GHC.Base.Functor (Focus.Focus element m)
instance GHC.Base.Monad m => GHC.Base.Applicative (Focus.Focus element m)
instance GHC.Base.Monad m => GHC.Base.Monad (Focus.Focus element m)
instance Control.Monad.Trans.Class.MonadTrans (Focus.Focus element)
