--------------------------------------------------

-- | Retrieve the first value targeted by a 'Fold' or 'Traversal' (or 'Just' the result
-- from a 'Getter' or 'Lens'). See also 'firstOf' and '^?', which are similar with
-- some subtle differences (explained below).
--
-- @
-- 'Data.Maybe.listToMaybe' '.' 'toList' ≡ 'preview' 'folded'
-- @
--
-- @
-- 'preview' = 'view' '.' 'pre'
-- @
-- 
--
-- Unlike '^?', this function uses a 
-- 'Control.Monad.Reader.MonadReader' to read the value to be focused in on.
-- This allows one to pass the value as the last argument by using the 
-- 'Control.Monad.Reader.MonadReader' instance for @(->) s@
-- However, it may also be used as part of some deeply nested transformer stack.
--
-- 'preview' uses a monoidal value to obtain the result.
-- This means that it generally has good performance, but can occasionally cause space leaks
-- or even stack overflows on some data types.
-- There is another function, 'firstOf', which avoids these issues at the cost of
-- a slight constant performance cost and a little less flexibility.
--
-- It may be helpful to think of 'preview' as having one of the following
-- more specialized types:
-- 
-- @
-- 'preview' :: 'Getter' s a     -> s -> 'Maybe' a
-- 'preview' :: 'Fold' s a       -> s -> 'Maybe' a
-- 'preview' :: 'Lens'' s a      -> s -> 'Maybe' a
-- 'preview' :: 'Iso'' s a       -> s -> 'Maybe' a
-- 'preview' :: 'Traversal'' s a -> s -> 'Maybe' a
-- @
--
--
-- @
-- 'preview' :: 'MonadReader' s m => 'Getter' s a     -> m ('Maybe' a)
-- 'preview' :: 'MonadReader' s m => 'Fold' s a       -> m ('Maybe' a)
-- 'preview' :: 'MonadReader' s m => 'Lens'' s a      -> m ('Maybe' a)
-- 'preview' :: 'MonadReader' s m => 'Iso'' s a       -> m ('Maybe' a)
-- 'preview' :: 'MonadReader' s m => 'Traversal'' s a -> m ('Maybe' a)
-- 
-- @
preview :: MonadReader s m => Getting (First a) s a -> m (Maybe a)
preview l = asks (getFirst #. foldMapOf l (First #. Just))
{-# INLINE preview #-}

-- | Retrieve the first index and value targeted by a 'Fold' or 'Traversal' (or 'Just' the resu
preview :: MonadReader s m => Getting (First a) s a -> m (Maybe a)
preview l = asks (getFirst #. foldMapOf l (First #. Just))
preview l = asks (getFirst #. foldMapOf l (First #. Just))