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

-- | microlens support for Reader/Writer/State from mtl
--   
--   This package contains functions (like view or +=) which
--   work on MonadReader, MonadWriter, and MonadState
--   from the mtl package.
--   
--   This package is a part of the microlens family; see the readme
--   on Github.
@package microlens-mtl
@version 0.2.0.1

-- | This module lets you define your own instances of Zoom and
--   Magnify.
--   
--   The warning from Lens.Micro.Internal applies to this module as
--   well. Don't export functions that have Zoom or Magnify
--   in their type signatures. If you absolutely need to define an instance
--   (e.g. for internal use), only do it for your own types, because
--   otherwise I might add an instance to one of the microlens packages
--   later and if our instances are different it might lead to subtle bugs.
module Lens.Micro.Mtl.Internal

-- | This type family is used by Zoom to describe the common effect
--   type.
type family Zoomed (m :: * -> *) :: * -> * -> *
class (MonadState s m, MonadState t n) => Zoom m n s t | m -> s, n -> t, m t -> n, n s -> m

-- | When you're in a state monad, this function lets you operate on a part
--   of your state. For instance, if your state was a record containing a
--   position field, after zooming position would become
--   your whole state (and when you modify it, the bigger structure would
--   be modified as well).
--   
--   (Your State / StateT or RWS / RWST can be
--   anywhere in the stack, but you can't use zoom with arbitrary
--   MonadState because it doesn't provide any methods to change the
--   type of the state. See this issue for details.)
--   
--   For the sake of the example, let's define some types first:
--   
--   
--   data Position = Position {
--     _x, _y :: Int }
--   
--   data Player = Player {
--     _position :: Position,
--     ... }
--   
--   data Game = Game {
--     _player :: Player,
--     _obstacles :: [Position],
--     ... }
--   
--   concat <$> mapM makeLenses [''Position, ''Player, ''Game]
--   
--   
--   Now, here's an action that moves the player north-east:
--   
--   
--   moveNE :: State Game ()
--   moveNE = do
--     player.position.x += 1
--     player.position.y += 1
--   
--   
--   With zoom, you can use player.position to focus just
--   on a part of the state:
--   
--   
--   moveNE :: State Game ()
--   moveNE = do
--     zoom (player.position) $ do
--       x += 1
--       y += 1
--   
--   
--   You can just as well use it for retrieving things out of the state:
--   
--   
--   getCoords :: State Game (Int, Int)
--   getCoords = zoom (player.position) ((,) <$> use x <*> use y)
--   
--   
--   Or more explicitly:
--   
--   
--   getCoords = zoom (player.position) $ do
--     x' <- use x
--     y' <- use y
--     return (x', y')
--   
--   
--   When you pass a traversal to zoom, it'll work as a loop. For
--   instance, here we move all obstacles:
--   
--   
--   moveObstaclesNE :: State Game ()
--   moveObstaclesNE = do
--     zoom (obstacles.each) $ do
--       x += 1
--       y += 1
--   
--   
--   If the action returns a result, all results would be combined with
--   <> – the same way they're combined when ^. is
--   passed a traversal. In this example, moveObstaclesNE returns
--   a list of old coordinates of obstacles in addition to moving them:
--   
--   
--   moveObstaclesNE = do
--     xys <- zoom (obstacles.each) $ do
--       -- Get old coordinates.
--       x' <- use x
--       y' <- use y
--       -- Update them.
--       x .= x' + 1
--       y .= y' + 1
--       -- Return a single-element list with old coordinates.
--       return [(x', y')]
--     ...
--   
--   
--   Finally, you might need to write your own instances of Zoom if
--   you use newtyped transformers in your monad stack. This can
--   be done as follows:
--   
--   
--   import Lens.Micro.Mtl.Internal
--   
--   type instance Zoomed (MyStateT s m) = Zoomed (StateT s m)
--   
--   instance Monad m => Zoom (MyStateT s m) (MyStateT t m) s t where
--       zoom l (MyStateT m) = MyStateT (zoom l m)
--   
zoom :: Zoom m n s t => LensLike' (Zoomed m c) t s -> m c -> n c
infixr 2 `zoom`

-- | This type family is used by Magnify to describe the common
--   effect type.
type family Magnified (m :: * -> *) :: * -> * -> *
class (MonadReader b m, MonadReader a n) => Magnify m n b a | m -> b, n -> a, m a -> n, n b -> m

-- | This is an equivalent of local which lets you apply a getter to
--   your environment instead of merely applying a function (and it also
--   lets you change the type of the environment).
--   
--   
--   local   :: (r -> r)   -> Reader r a -> Reader r a
--   magnify :: Getter r x -> Reader x a -> Reader r a
--   
--   
--   magnify works with Reader / ReaderT, RWS /
--   RWST, and (->).
--   
--   Here's an example of magnify being used to work with a part of
--   a bigger config. First, the types:
--   
--   
--   data URL = URL {
--     _protocol :: Maybe String,
--     _path :: String }
--   
--   data Config = Config {
--     _base :: URL,
--     ... }
--   
--   makeLenses ''URL
--   makeLenses ''Config
--   
--   
--   Now, let's define a function which returns the base url:
--   
--   
--   getBase :: Reader Config String
--   getBase = do
--     protocol <- fromMaybe "https" <$> view (base.protocol)
--     path     <- view (base.path)
--     return (protocol ++ path)
--   
--   
--   With magnify, we can factor out base:
--   
--   
--   getBase = magnify base $ do
--     protocol <- fromMaybe "https" <$> view protocol
--     path     <- view path
--     return (protocol ++ path)
--   
--   
--   This concludes the example.
--   
--   Finally, you should know writing instances of Magnify for your
--   own types can be done as follows:
--   
--   
--   import Lens.Micro.Mtl.Internal
--   
--   type instance Magnified (MyReaderT r m) = Magnified (ReaderT r m)
--   
--   instance Monad m => Magnify (MyReaderT r m) (MyReaderT t m) r t where
--       magnify l (MyReaderT m) = MyReaderT (magnify l m)
--   
magnify :: Magnify m n b a => LensLike' (Magnified m c) a b -> m c -> n c
infixr 2 `magnify`

-- | Used by Zoom to zoom into StateT.
newtype Focusing m s a
Focusing :: m (s, a) -> Focusing m s a
[unfocusing] :: Focusing m s a -> m (s, a)

-- | Used by Zoom to zoom into RWST.
newtype FocusingWith w m s a
FocusingWith :: m (s, a, w) -> FocusingWith w m s a
[unfocusingWith] :: FocusingWith w m s a -> m (s, a, w)

-- | Used by Zoom to zoom into WriterT.
newtype FocusingPlus w k s a
FocusingPlus :: k (s, w) a -> FocusingPlus w k s a
[unfocusingPlus] :: FocusingPlus w k s a -> k (s, w) a

-- | Used by Zoom to zoom into MaybeT or ListT.
newtype FocusingOn f k s a
FocusingOn :: k (f s) a -> FocusingOn f k s a
[unfocusingOn] :: FocusingOn f k s a -> k (f s) a

-- | Used by Zoom to zoom into ErrorT.
newtype FocusingMay k s a
FocusingMay :: k (May s) a -> FocusingMay k s a
[unfocusingMay] :: FocusingMay k s a -> k (May s) a

-- | Used by Zoom to zoom into ErrorT.
newtype FocusingErr e k s a
FocusingErr :: k (Err e s) a -> FocusingErr e k s a
[unfocusingErr] :: FocusingErr e k s a -> k (Err e s) a

-- | Wrap a monadic effect with a phantom type argument.
newtype Effect m r a
Effect :: m r -> Effect m r a
[getEffect] :: Effect m r a -> m r

-- | Wrap a monadic effect with a phantom type argument. Used when
--   magnifying RWST.
newtype EffectRWS w st m s a
EffectRWS :: (st -> m (s, st, w)) -> EffectRWS w st m s a
[getEffectRWS] :: EffectRWS w st m s a -> st -> m (s, st, w)

-- | Make a Monoid out of Maybe for error handling.
newtype May a
May :: Maybe a -> May a
[getMay] :: May a -> Maybe a

-- | Make a Monoid out of Either for error handling.
newtype Err e a
Err :: Either e a -> Err e a
[getErr] :: Err e a -> Either e a
instance (GHC.Base.Monad m, GHC.Base.Monoid w) => Lens.Micro.Mtl.Internal.Magnify (Control.Monad.Trans.RWS.Strict.RWST b w s m) (Control.Monad.Trans.RWS.Strict.RWST a w s m) b a
instance (GHC.Base.Monad m, GHC.Base.Monoid w) => Lens.Micro.Mtl.Internal.Magnify (Control.Monad.Trans.RWS.Lazy.RWST b w s m) (Control.Monad.Trans.RWS.Lazy.RWST a w s m) b a
instance GHC.Base.Functor (Lens.Micro.Mtl.Internal.EffectRWS w st m s)
instance (GHC.Base.Monoid s, GHC.Base.Monoid w, GHC.Base.Monad m) => GHC.Base.Applicative (Lens.Micro.Mtl.Internal.EffectRWS w st m s)
instance GHC.Base.Monad m => Lens.Micro.Mtl.Internal.Magnify (Control.Monad.Trans.Reader.ReaderT b m) (Control.Monad.Trans.Reader.ReaderT a m) b a
instance GHC.Base.Functor (Lens.Micro.Mtl.Internal.Effect m r)
instance (GHC.Base.Monad m, GHC.Base.Monoid r) => GHC.Base.Monoid (Lens.Micro.Mtl.Internal.Effect m r a)
instance (GHC.Base.Monad m, GHC.Base.Semigroup r) => GHC.Base.Semigroup (Lens.Micro.Mtl.Internal.Effect m r a)
instance (GHC.Base.Monad m, GHC.Base.Monoid r) => GHC.Base.Applicative (Lens.Micro.Mtl.Internal.Effect m r)
instance Lens.Micro.Mtl.Internal.Magnify ((->) b) ((->) a) b a
instance Lens.Micro.Mtl.Internal.Magnify m n b a => Lens.Micro.Mtl.Internal.Magnify (Control.Monad.Trans.Identity.IdentityT m) (Control.Monad.Trans.Identity.IdentityT n) b a
instance GHC.Base.Monad z => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.State.Strict.StateT s z) (Control.Monad.Trans.State.Strict.StateT t z) s t
instance GHC.Base.Monad z => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.State.Lazy.StateT s z) (Control.Monad.Trans.State.Lazy.StateT t z) s t
instance Lens.Micro.Mtl.Internal.Zoom m n s t => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.Reader.ReaderT e m) (Control.Monad.Trans.Reader.ReaderT e n) s t
instance Lens.Micro.Mtl.Internal.Zoom m n s t => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.Identity.IdentityT m) (Control.Monad.Trans.Identity.IdentityT n) s t
instance (GHC.Base.Monoid w, GHC.Base.Monad z) => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.RWS.Strict.RWST r w s z) (Control.Monad.Trans.RWS.Strict.RWST r w t z) s t
instance (GHC.Base.Monoid w, GHC.Base.Monad z) => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.RWS.Lazy.RWST r w s z) (Control.Monad.Trans.RWS.Lazy.RWST r w t z) s t
instance (GHC.Base.Monoid w, Lens.Micro.Mtl.Internal.Zoom m n s t) => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.Writer.Strict.WriterT w m) (Control.Monad.Trans.Writer.Strict.WriterT w n) s t
instance (GHC.Base.Monoid w, Lens.Micro.Mtl.Internal.Zoom m n s t) => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.Writer.Lazy.WriterT w m) (Control.Monad.Trans.Writer.Lazy.WriterT w n) s t
instance Lens.Micro.Mtl.Internal.Zoom m n s t => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.List.ListT m) (Control.Monad.Trans.List.ListT n) s t
instance Lens.Micro.Mtl.Internal.Zoom m n s t => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.Maybe.MaybeT m) (Control.Monad.Trans.Maybe.MaybeT n) s t
instance (Control.Monad.Trans.Error.Error e, Lens.Micro.Mtl.Internal.Zoom m n s t) => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.Error.ErrorT e m) (Control.Monad.Trans.Error.ErrorT e n) s t
instance Lens.Micro.Mtl.Internal.Zoom m n s t => Lens.Micro.Mtl.Internal.Zoom (Control.Monad.Trans.Except.ExceptT e m) (Control.Monad.Trans.Except.ExceptT e n) s t
instance GHC.Base.Functor (k (Lens.Micro.Mtl.Internal.Err e s)) => GHC.Base.Functor (Lens.Micro.Mtl.Internal.FocusingErr e k s)
instance GHC.Base.Applicative (k (Lens.Micro.Mtl.Internal.Err e s)) => GHC.Base.Applicative (Lens.Micro.Mtl.Internal.FocusingErr e k s)
instance GHC.Base.Monoid a => GHC.Base.Monoid (Lens.Micro.Mtl.Internal.Err e a)
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Lens.Micro.Mtl.Internal.Err e a)
instance GHC.Base.Functor (k (Lens.Micro.Mtl.Internal.May s)) => GHC.Base.Functor (Lens.Micro.Mtl.Internal.FocusingMay k s)
instance GHC.Base.Applicative (k (Lens.Micro.Mtl.Internal.May s)) => GHC.Base.Applicative (Lens.Micro.Mtl.Internal.FocusingMay k s)
instance GHC.Base.Monoid a => GHC.Base.Monoid (Lens.Micro.Mtl.Internal.May a)
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Lens.Micro.Mtl.Internal.May a)
instance GHC.Base.Functor (k (f s)) => GHC.Base.Functor (Lens.Micro.Mtl.Internal.FocusingOn f k s)
instance GHC.Base.Applicative (k (f s)) => GHC.Base.Applicative (Lens.Micro.Mtl.Internal.FocusingOn f k s)
instance GHC.Base.Functor (k (s, w)) => GHC.Base.Functor (Lens.Micro.Mtl.Internal.FocusingPlus w k s)
instance GHC.Base.Applicative (k (s, w)) => GHC.Base.Applicative (Lens.Micro.Mtl.Internal.FocusingPlus w k s)
instance GHC.Base.Monad m => GHC.Base.Functor (Lens.Micro.Mtl.Internal.FocusingWith w m s)
instance (GHC.Base.Monad m, GHC.Base.Monoid s, GHC.Base.Monoid w) => GHC.Base.Applicative (Lens.Micro.Mtl.Internal.FocusingWith w m s)
instance GHC.Base.Monad m => GHC.Base.Functor (Lens.Micro.Mtl.Internal.Focusing m s)
instance (GHC.Base.Monad m, GHC.Base.Monoid s) => GHC.Base.Applicative (Lens.Micro.Mtl.Internal.Focusing m s)

module Lens.Micro.Mtl

-- | view is a synonym for (^.), generalised for
--   MonadReader (we are able to use it instead of (^.) since
--   functions are instances of the MonadReader class):
--   
--   
--   >>> view _1 (1, 2)
--   1
--   
--   
--   When you're using Reader for config and your config type has
--   lenses generated for it, most of the time you'll be using view
--   instead of asks:
--   
--   
--   doSomething :: (MonadReader Config m) => m Int
--   doSomething = do
--     thingy        <- view setting1  -- same as “asks (^. setting1)”
--     anotherThingy <- view setting2
--     ...
--   
view :: MonadReader s m => Getting a s a -> m a

-- | preview is a synonym for (^?), generalised for
--   MonadReader (just like view, which is a synonym for
--   (^.)).
--   
--   
--   >>> preview each [1..5]
--   Just 1
--   
preview :: MonadReader s m => Getting (First a) s a -> m (Maybe a)

-- | use is (^.) (or view) which implicitly operates
--   on the state; for instance, if your state is a record containing a
--   field foo, you can write
--   
--   
--   x <- use foo
--   
--   
--   to extract foo from the state. In other words, use is
--   the same as gets, but for getters instead of functions.
--   
--   The implementation of use is straightforward:
--   
--   
--   use l = gets (view l)
--   
--   
--   If you need to extract something with a fold or traversal, you need
--   preuse.
use :: MonadState s m => Getting a s a -> m a

-- | preuse is (^?) (or preview) which implicitly
--   operates on the state – it takes the state and applies a traversal (or
--   fold) to it to extract the 1st element the traversal points at.
--   
--   
--   preuse l = gets (preview l)
--   
preuse :: MonadState s m => Getting (First a) s a -> m (Maybe a)

-- | Modify state by applying a function to a part of the state. An
--   example:
--   
--   
--   >>> execState (do _1 %= (+1); _2 %= reverse) (1,"hello")
--   (2,"olleh")
--   
--   
--   Implementation:
--   
--   
--   l %= f = modify (l %~ f)
--   
--   
--   If you also want to get the value before/after the modification, use
--   (<<%=)/(<%=).
--   
--   There are a few specialised versions of (%=) which mimic C
--   operators:
--   
--   
--   
- (+=) for addition
--   
- (-=) for substraction
--   
- (*=) for multiplication
--   
- (//=) for division
--   
(%=) :: MonadState s m => ASetter s s a b -> (a -> b) -> m ()
infix 4 %=

-- | A synonym for (%=).
modifying :: MonadState s m => ASetter s s a b -> (a -> b) -> m ()

-- | Modify state by “assigning” a value to a part of the state.
--   
--   This is merely (.~) which works in MonadState:
--   
--   
--   l .= x = modify (l .~ x)
--   
--   
--   If you also want to know the value that was replaced by (.=),
--   use (<<.=).
(.=) :: MonadState s m => ASetter s s a b -> b -> m ()
infix 4 .=

-- | A synonym for (.=).
assign :: MonadState s m => ASetter s s a b -> b -> m ()

-- | (?=) is a version of (.=) that wraps the value into
--   Just before setting.
--   
--   
--   l ?= b = l .= Just b
--   
--   
--   It can be useful in combination with at.
(?=) :: MonadState s m => ASetter s s a (Maybe b) -> b -> m ()
infix 4 ?=

-- | (<~) is a version of (.=) that takes a monadic value
--   (and then executes it and assigns the result to the lens).
--   
--   
--   l <~ mb = do
--     b <- mb
--     l .= b
--   
(<~) :: MonadState s m => ASetter s s a b -> m b -> m ()
infixr 2 <~

-- | This can be used to chain lens operations using op= syntax
--   rather than op~ syntax for simple non-type-changing cases.
--   >>> (10,20) & _1 .~ 30 & _2 .~ 40 (30,40)
--   
--   
--   >>> (10,20) &~ do _1 .= 30; _2 .= 40
--   (30,40)
--   
--   
--   This does not support type-changing assignment, e.g.
--   
--   
--   >>> (10,20) & _1 .~ "hello"
--   ("hello",20)
--   
(&~) :: s -> State s a -> s
infixl 1 &~
(+=) :: (MonadState s m, Num a) => ASetter s s a a -> a -> m ()
infix 4 +=
(-=) :: (MonadState s m, Num a) => ASetter s s a a -> a -> m ()
infix 4 -=
(*=) :: (MonadState s m, Num a) => ASetter s s a a -> a -> m ()
infix 4 *=
(//=) :: (MonadState s m, Fractional a) => ASetter s s a a -> a -> m ()
infix 4 //=

-- | Modify state and return the modified (new) value.
--   
--   
--   l <%= f = do
--     l %= f
--     use l
--   
(<%=) :: MonadState s m => LensLike ((,) b) s s a b -> (a -> b) -> m b
infix 4 <%=

-- | Set state and return new value.
--   
--   
--   l <.= b = do
--     l .= b
--     return b
--   
(<.=) :: MonadState s m => LensLike ((,) b) s s a b -> b -> m b
infix 4 <.=

-- | (<?=) is a version of (<.=) that wraps the value
--   into Just before setting.
--   
--   
--   l <?= b = do
--     l .= Just b
--     return b
--   
--   
--   It can be useful in combination with at.
(<?=) :: MonadState s m => LensLike ((,) b) s s a (Maybe b) -> b -> m b
infix 4 <?=

-- | Modify state and return the old value (i.e. as it was before the
--   modificaton).
--   
--   
--   l <<%= f = do
--     old <- use l
--     l %= f
--     return old
--   
(<<%=) :: MonadState s m => LensLike ((,) a) s s a b -> (a -> b) -> m a
infix 4 <<%=

-- | Set state and return the old value.
--   
--   
--   l <<.= b = do
--     old <- use l
--     l .= b
--     return old
--   
(<<.=) :: MonadState s m => LensLike ((,) a) s s a b -> b -> m a
infix 4 <<.=

-- | When you're in a state monad, this function lets you operate on a part
--   of your state. For instance, if your state was a record containing a
--   position field, after zooming position would become
--   your whole state (and when you modify it, the bigger structure would
--   be modified as well).
--   
--   (Your State / StateT or RWS / RWST can be
--   anywhere in the stack, but you can't use zoom with arbitrary
--   MonadState because it doesn't provide any methods to change the
--   type of the state. See this issue for details.)
--   
--   For the sake of the example, let's define some types first:
--   
--   
--   data Position = Position {
--     _x, _y :: Int }
--   
--   data Player = Player {
--     _position :: Position,
--     ... }
--   
--   data Game = Game {
--     _player :: Player,
--     _obstacles :: [Position],
--     ... }
--   
--   concat <$> mapM makeLenses [''Position, ''Player, ''Game]
--   
--   
--   Now, here's an action that moves the player north-east:
--   
--   
--   moveNE :: State Game ()
--   moveNE = do
--     player.position.x += 1
--     player.position.y += 1
--   
--   
--   With zoom, you can use player.position to focus just
--   on a part of the state:
--   
--   
--   moveNE :: State Game ()
--   moveNE = do
--     zoom (player.position) $ do
--       x += 1
--       y += 1
--   
--   
--   You can just as well use it for retrieving things out of the state:
--   
--   
--   getCoords :: State Game (Int, Int)
--   getCoords = zoom (player.position) ((,) <$> use x <*> use y)
--   
--   
--   Or more explicitly:
--   
--   
--   getCoords = zoom (player.position) $ do
--     x' <- use x
--     y' <- use y
--     return (x', y')
--   
--   
--   When you pass a traversal to zoom, it'll work as a loop. For
--   instance, here we move all obstacles:
--   
--   
--   moveObstaclesNE :: State Game ()
--   moveObstaclesNE = do
--     zoom (obstacles.each) $ do
--       x += 1
--       y += 1
--   
--   
--   If the action returns a result, all results would be combined with
--   <> – the same way they're combined when ^. is
--   passed a traversal. In this example, moveObstaclesNE returns
--   a list of old coordinates of obstacles in addition to moving them:
--   
--   
--   moveObstaclesNE = do
--     xys <- zoom (obstacles.each) $ do
--       -- Get old coordinates.
--       x' <- use x
--       y' <- use y
--       -- Update them.
--       x .= x' + 1
--       y .= y' + 1
--       -- Return a single-element list with old coordinates.
--       return [(x', y')]
--     ...
--   
--   
--   Finally, you might need to write your own instances of Zoom if
--   you use newtyped transformers in your monad stack. This can
--   be done as follows:
--   
--   
--   import Lens.Micro.Mtl.Internal
--   
--   type instance Zoomed (MyStateT s m) = Zoomed (StateT s m)
--   
--   instance Monad m => Zoom (MyStateT s m) (MyStateT t m) s t where
--       zoom l (MyStateT m) = MyStateT (zoom l m)
--   
zoom :: Zoom m n s t => LensLike' (Zoomed m c) t s -> m c -> n c
infixr 2 `zoom`

-- | This is an equivalent of local which lets you apply a getter to
--   your environment instead of merely applying a function (and it also
--   lets you change the type of the environment).
--   
--   
--   local   :: (r -> r)   -> Reader r a -> Reader r a
--   magnify :: Getter r x -> Reader x a -> Reader r a
--   
--   
--   magnify works with Reader / ReaderT, RWS /
--   RWST, and (->).
--   
--   Here's an example of magnify being used to work with a part of
--   a bigger config. First, the types:
--   
--   
--   data URL = URL {
--     _protocol :: Maybe String,
--     _path :: String }
--   
--   data Config = Config {
--     _base :: URL,
--     ... }
--   
--   makeLenses ''URL
--   makeLenses ''Config
--   
--   
--   Now, let's define a function which returns the base url:
--   
--   
--   getBase :: Reader Config String
--   getBase = do
--     protocol <- fromMaybe "https" <$> view (base.protocol)
--     path     <- view (base.path)
--     return (protocol ++ path)
--   
--   
--   With magnify, we can factor out base:
--   
--   
--   getBase = magnify base $ do
--     protocol <- fromMaybe "https" <$> view protocol
--     path     <- view path
--     return (protocol ++ path)
--   
--   
--   This concludes the example.
--   
--   Finally, you should know writing instances of Magnify for your
--   own types can be done as follows:
--   
--   
--   import Lens.Micro.Mtl.Internal
--   
--   type instance Magnified (MyReaderT r m) = Magnified (ReaderT r m)
--   
--   instance Monad m => Magnify (MyReaderT r m) (MyReaderT t m) r t where
--       magnify l (MyReaderT m) = MyReaderT (magnify l m)
--   
magnify :: Magnify m n b a => LensLike' (Magnified m c) a b -> m c -> n c
infixr 2 `magnify`
