    {-# LANGUAGE TypeOperators #-}
    module Data.Label.MaybeM
    (
    -- * 'MonadState' lens operations.
      gets

    -- * 'MonadReader' lens operations.
    , asks
    )
    where

    import Control.Monad
    import Data.Label.Maybe ((:~>))
    import qualified Control.Monad.Reader as M
    import qualified Control.Monad.State  as M
    import qualified Data.Label.Maybe     as L

    -- | Get a value out of state, pointed to by the specified lens that might
    -- fail.  When the lens getter fails this computation will fall back to
    -- `mzero'.

    gets :: (M.MonadState f m, MonadPlus m) => (f :~> a) -> m a
    gets l = (L.get l `liftM` M.get) >>= (mzero `maybe` return)

    -- | Fetch a value, pointed to by a lens that might fail, out of a reader
    -- environment. When the lens getter fails this computation will fall back to
    -- `mzero'.

    asks :: (M.MonadReader f m, MonadPlus m) => (f :~> a) -> m a
    asks l = (L.get l `liftM` M.ask) >>= (mzero `maybe` return)