    ------------------------------------------------------------------------------
    -- | The Heist snaplet makes it easy to add Heist to your application and use
    -- it in other snaplets.
    --

    module Snap.Snaplet.Heist
      (
      -- * Heist and its type class
        Heist
      , HasHeist(..)

      -- * Initializer Functions
      -- $initializerSection
      , heistInit
      , heistInit'
      , Unclassed.heistReloader
      , Unclassed.setInterpreted
      , Unclassed.getCurHeistConfig
      , addTemplates
      , addTemplatesAt
      , Unclassed.addConfig
      , getHeistState
      , modifyHeistState
      , withHeistState

      -- * Handler Functions
      -- $handlerSection
      , gRender
      , gRenderAs
      , gHeistServe
      , gHeistServeSingle
      , chooseMode

      , cRender
      , cRenderAs
      , cHeistServe
      , cHeistServeSingle

      , render
      , renderAs
      , heistServe
      , heistServeSingle
      , heistLocal
      , withSplices
      , renderWithSplices

      -- * Writing Splices
      -- $spliceSection
      , Unclassed.SnapletHeist
      , Unclassed.SnapletCSplice
      , Unclassed.SnapletISplice

      , clearHeistCache
      ) where

    ------------------------------------------------------------------------------
    import           Prelude hiding (id, (.))
    import           Control.Monad.State
    import           Data.ByteString (ByteString)
    import           Heist
    ------------------------------------------------------------------------------
    import           Snap.Snaplet
    import           Snap.Snaplet.Heist.Internal
    import qualified Snap.Snaplet.HeistNoClass as Unclassed
    import           Snap.Snaplet.HeistNoClass ( heistInit
                                               , heistInit'
                                               , clearHeistCache
                                               )

    ------------------------------------------------------------------------------
    -- | A single snaplet should never need more than one instance of Heist as a
    -- subsnaplet.  This type class allows you to make it easy for other snaplets
    -- to get the lens that identifies the heist snaplet.  Here's an example of
    -- how the heist snaplet might be declared:
    --
    -- > data App = App { _heist :: Snaplet (Heist App) }
    -- > makeLenses ''App
    -- >
    -- > instance HasHeist App where heistLens = subSnaplet heist
    -- >
    -- > appInit = makeSnaplet "app" "" Nothing $ do
    -- >     h <- nestSnaplet "heist" heist $ heistInit "templates"
    -- >     addConfig h heistConfigWithMyAppSplices
    -- >     return $ App h
    class HasHeist b where
        -- | A lens to the Heist snaplet.  The b parameter to Heist will
        -- typically be the base state of your application.
        heistLens :: SnapletLens (Snaplet b) (Heist b)

    -- $initializerSection
    -- This section contains functions for use in setting up your Heist state
    -- during initialization.

    ------------------------------------------------------------------------------
    -- | Adds templates to the Heist HeistState.  Other snaplets should use
    -- this function to add their own templates.  The templates are automatically
    -- read from the templates directory in the current snaplet's filesystem root.
    addTemplates :: HasHeist b
                 => Snaplet (Heist b)
                 -> ByteString
                     -- ^ The url prefix for the template routes
                 -> Initializer b v ()
    addTemplates :: Snaplet (Heist b) -> ByteString -> Initializer b v ()
    addTemplates h :: Snaplet (Heist b)
    h pfx :: ByteString
    pfx = SnapletLens (Snaplet b) (Heist b)
    -> Initializer b (Heist b) () -> Initializer b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (Snaplet (Heist b) -> ByteString -> Initializer b (Heist b) ()
    forall b.
    Snaplet (Heist b) -> ByteString -> Initializer b (Heist b) ()
    Unclassed.addTemplates Snaplet (Heist b)
    h ByteString
    pfx)

    ------------------------------------------------------------------------------
    -- | Adds templates to the Heist HeistState, and lets you specify where
    -- they are found in the filesystem.  Note that the path to the template
    -- directory is an absolute path.  This allows you more flexibility in where
    -- your templates are located, but means that you have to explicitly call
    -- getSnapletFilePath if you want your snaplet to use templates within its
    -- normal directory structure.
    addTemplatesAt :: HasHeist b
                   => Snaplet (Heist b)
                   -> ByteString
                       -- ^ URL prefix for template routes
                   -> FilePath
                       -- ^ Path to templates
                   -> Initializer b v ()
    addTemplatesAt :: Snaplet (Heist b) -> ByteString -> FilePath -> Initializer b v ()
    addTemplatesAt h :: Snaplet (Heist b)
    h pfx :: ByteString
    pfx p :: FilePath
    p =
        SnapletLens (Snaplet b) (Heist b)
    -> Initializer b (Heist b) () -> Initializer b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (Snaplet (Heist b)
    -> ByteString -> FilePath -> Initializer b (Heist b) ()
    forall b.
    Snaplet (Heist b)
    -> ByteString -> FilePath -> Initializer b (Heist b) ()
    Unclassed.addTemplatesAt Snaplet (Heist b)
    h ByteString
    pfx FilePath
    p)

    ------------------------------------------------------------------------------
    -- | More general function allowing arbitrary HeistState modification.
    getHeistState :: (HasHeist b)
                  => Handler b v (HeistState (Handler b b))
    getHeistState :: Handler b v (HeistState (Handler b b))
    getHeistState = SnapletLens (Snaplet b) (Heist b)
    -> Handler b v (HeistState (Handler b b))
    forall b v.
    SnapletLens (Snaplet b) (Heist b)
    -> Handler b v (HeistState (Handler b b))
    Unclassed.getHeistState SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens

    ------------------------------------------------------------------------------
    -- | More general function allowing arbitrary HeistState modification.
    modifyHeistState :: (HasHeist b)
                     => (HeistState (Handler b b) -> HeistState (Handler b b))
                         -- ^ HeistState modifying function
                     -> Initializer b v ()
    modifyHeistState :: (HeistState (Handler b b) -> HeistState (Handler b b))
    -> Initializer b v ()
    modifyHeistState = SnapletLens (Snaplet b) (Heist b)
    -> (HeistState (Handler b b) -> HeistState (Handler b b))
    -> Initializer b v ()
    forall b v.
    SnapletLens (Snaplet b) (Heist b)
    -> (HeistState (Handler b b) -> HeistState (Handler b b))
    -> Initializer b v ()
    Unclassed.modifyHeistState' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens

    ------------------------------------------------------------------------------
    -- | Runs a function on with the Heist snaplet's 'HeistState'.
    withHeistState :: (HasHeist b)
                   => (HeistState (Handler b b) -> a)
                       -- ^ HeistState function to run
                   -> Handler b v a
    withHeistState :: (HeistState (Handler b b) -> a) -> Handler b v a
    withHeistState = SnapletLens (Snaplet b) (Heist b)
    -> (HeistState (Handler b b) -> a) -> Handler b v a
    forall b a v.
    SnapletLens (Snaplet b) (Heist b)
    -> (HeistState (Handler b b) -> a) -> Handler b v a
    Unclassed.withHeistState' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens

    -- $handlerSection
    -- This section contains functions in the 'Handler' monad that you'll use in
    -- processing requests.  Functions beginning with a 'g' prefix use generic
    -- rendering that checks the preferred rendering mode and chooses
    -- appropriately.  Functions beginning with a 'c' prefix use compiled template
    -- rendering.  The other functions use the older interpreted rendering.
    -- Interpreted splices added with addConfig will only work if you use
    -- interpreted rendering.
    --
    -- The generic functions are useful if you are writing general snaplets that
    -- use heist, but need to work for applications that use either interpreted
    -- or compiled mode.

    ------------------------------------------------------------------------------
    -- | Generic version of 'render'/'cRender'.
    gRender :: HasHeist b
            => ByteString
                -- ^ Template name
            -> Handler b v ()
    gRender :: ByteString -> Handler b v ()
    gRender t :: ByteString
    t = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (ByteString -> Handler b (Heist b) ()
    forall b. ByteString -> Handler b (Heist b) ()
    Unclassed.gRender ByteString
    t)

    ------------------------------------------------------------------------------
    -- | Generic version of 'renderAs'/'cRenderAs'.
    gRenderAs :: HasHeist b
              => ByteString
                  -- ^ Content type to render with
              -> ByteString
                  -- ^ Template name
              -> Handler b v ()
    gRenderAs :: ByteString -> ByteString -> Handler b v ()
    gRenderAs ct :: ByteString
    ct t :: ByteString
    t = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (ByteString -> ByteString -> Handler b (Heist b) ()
    forall b. ByteString -> ByteString -> Handler b (Heist b) ()
    Unclassed.gRenderAs ByteString
    ct ByteString
    t)

    ------------------------------------------------------------------------------
    -- | Generic version of 'heistServe'/'cHeistServe'.
    gHeistServe :: HasHeist b => Handler b v ()
    gHeistServe :: Handler b v ()
    gHeistServe = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens Handler b (Heist b) ()
    forall b. Handler b (Heist b) ()
    Unclassed.gHeistServe

    ------------------------------------------------------------------------------
    -- | Generic version of 'heistServeSingle'/'cHeistServeSingle'.
    gHeistServeSingle :: HasHeist b
                      => ByteString
                          -- ^ Template name
                      -> Handler b v ()
    gHeistServeSingle :: ByteString -> Handler b v ()
    gHeistServeSingle t :: ByteString
    t = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (ByteString -> Handler b (Heist b) ()
    forall b. ByteString -> Handler b (Heist b) ()
    Unclassed.gHeistServeSingle ByteString
    t)

    ------------------------------------------------------------------------------
    -- | Chooses between a compiled action and an interpreted action based on the
    -- configured default.
    chooseMode :: HasHeist b
               => Handler b v a
                   -- ^ A compiled action
               -> Handler b v a
                   -- ^ An interpreted action
               -> Handler b v a
    chooseMode :: Handler b v a -> Handler b v a -> Handler b v a
    chooseMode cAction :: Handler b v a
    cAction iAction :: Handler b v a
    iAction = do
        DefaultMode
    mode <- SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) DefaultMode -> Handler b v DefaultMode
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (Handler b (Heist b) DefaultMode -> Handler b v DefaultMode)
    -> Handler b (Heist b) DefaultMode -> Handler b v DefaultMode
    forall a b. (a -> b) -> a -> b
    $ (Heist b -> DefaultMode) -> Handler b (Heist b) DefaultMode
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets Heist b -> DefaultMode
    forall b. Heist b -> DefaultMode
    _defMode
        case DefaultMode
    mode of
          Unclassed.Compiled -> Handler b v a
    cAction
          Unclassed.Interpreted -> Handler b v a
    iAction

    ------------------------------------------------------------------------------
    -- | Renders a compiled template as text\/html. If the given template is not
    -- found, this returns 'empty'.
    cRender :: HasHeist b
            => ByteString
                -- ^ Template name
            -> Handler b v ()
    cRender :: ByteString -> Handler b v ()
    cRender t :: ByteString
    t = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (ByteString -> Handler b (Heist b) ()
    forall b. ByteString -> Handler b (Heist b) ()
    Unclassed.cRender ByteString
    t)

    ------------------------------------------------------------------------------
    -- | Renders a compiled template as the given content type.  If the given
    -- template is not found, this returns 'empty'.
    cRenderAs :: HasHeist b
              => ByteString
                  -- ^ Content type to render with
              -> ByteString
                  -- ^ Template name
              -> Handler b v ()
    cRenderAs :: ByteString -> ByteString -> Handler b v ()
    cRenderAs ct :: ByteString
    ct t :: ByteString
    t = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (ByteString -> ByteString -> Handler b (Heist b) ()
    forall b. ByteString -> ByteString -> Handler b (Heist b) ()
    Unclassed.cRenderAs ByteString
    ct ByteString
    t)

    ------------------------------------------------------------------------------
    -- | A compiled version of 'heistServe'.
    cHeistServe :: HasHeist b => Handler b v ()
    cHeistServe :: Handler b v ()
    cHeistServe = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens Handler b (Heist b) ()
    forall b. Handler b (Heist b) ()
    Unclassed.cHeistServe

    ------------------------------------------------------------------------------
    -- | Analogous to 'fileServeSingle'. If the given template is not found,
    -- this throws an error.
    cHeistServeSingle :: HasHeist b
                     => ByteString
                         -- ^ Template name
                     -> Handler b v ()
    cHeistServeSingle :: ByteString -> Handler b v ()
    cHeistServeSingle t :: ByteString
    t = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (ByteString -> Handler b (Heist b) ()
    forall b. ByteString -> Handler b (Heist b) ()
    Unclassed.cHeistServeSingle ByteString
    t)

    ------------------------------------------------------------------------------
    -- | Renders a template as text\/html. If the given template is not found,
    -- this returns 'empty'.
    render :: HasHeist b
           => ByteString
               -- ^ Template name
           -> Handler b v ()
    render :: ByteString -> Handler b v ()
    render t :: ByteString
    t = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (ByteString -> Handler b (Heist b) ()
    forall b. ByteString -> Handler b (Heist b) ()
    Unclassed.render ByteString
    t)

    ------------------------------------------------------------------------------
    -- | Renders a template as the given content type.  If the given template
    -- is not found, this returns 'empty'.
    renderAs :: HasHeist b
             => ByteString
                 -- ^ Content type to render with
             -> ByteString
                 -- ^ Template name
             -> Handler b v ()
    renderAs :: ByteString -> ByteString -> Handler b v ()
    renderAs ct :: ByteString
    ct t :: ByteString
    t = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (ByteString -> ByteString -> Handler b (Heist b) ()
    forall b. ByteString -> ByteString -> Handler b (Heist b) ()
    Unclassed.renderAs ByteString
    ct ByteString
    t)

    ------------------------------------------------------------------------------
    -- | A handler that serves all the templates (similar to 'serveDirectory').
    -- If the template specified in the request path is not found, it returns
    -- 'empty'.  Also, this function does not serve any templates beginning with
    -- an underscore.  This gives you a way to prevent some templates from being
    -- served.  For example, you might have a template that contains only the
    -- navbar of your pages, and you probably wouldn't want that template to be
    -- visible to the user as a standalone template.  So if you put it in a file
    -- called \"_nav.tpl\", this function won't serve it.
    heistServe :: HasHeist b => Handler b v ()
    heistServe :: Handler b v ()
    heistServe = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens Handler b (Heist b) ()
    forall b. Handler b (Heist b) ()
    Unclassed.heistServe

    ------------------------------------------------------------------------------
    -- | Handler for serving a single template (similar to 'fileServeSingle'). If
    -- the given template is not found, this throws an error.
    heistServeSingle :: HasHeist b
                     => ByteString
                         -- ^ Template name
                     -> Handler b v ()
    heistServeSingle :: ByteString -> Handler b v ()
    heistServeSingle t :: ByteString
    t = SnapletLens (Snaplet b) (Heist b)
    -> Handler b (Heist b) () -> Handler b v ()
    forall (m :: * -> * -> * -> *) b v' a v.
    MonadSnaplet m =>
    SnapletLens (Snaplet b) v' -> m b v' a -> m b v a
    withTop' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens (ByteString -> Handler b (Heist b) ()
    forall b. ByteString -> Handler b (Heist b) ()
    Unclassed.heistServeSingle ByteString
    t)

    ------------------------------------------------------------------------------
    -- | Renders a template with a given set of splices.  This is syntax sugar for
    -- a common combination of heistLocal, bindSplices, and render.
    renderWithSplices :: HasHeist b
                      => ByteString
                          -- ^ Template name
                      -> Splices (Unclassed.SnapletISplice b)
                          -- ^ Splices to bind
                      -> Handler b v ()
    renderWithSplices :: ByteString -> Splices (SnapletISplice b) -> Handler b v ()
    renderWithSplices = SnapletLens (Snaplet b) (Heist b)
    -> ByteString -> Splices (SnapletISplice b) -> Handler b v ()
    forall b v.
    SnapletLens (Snaplet b) (Heist b)
    -> ByteString -> Splices (SnapletISplice b) -> Handler b v ()
    Unclassed.renderWithSplices' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens

    ------------------------------------------------------------------------------
    -- | Runs an action with additional splices bound into the Heist
    -- 'HeistState'.
    withSplices :: HasHeist b
                => Splices (Unclassed.SnapletISplice b)
                    -- ^ Splices to bind
                -> Handler b v a
                    -- ^ Handler to run
                -> Handler b v a
    withSplices :: Splices (SnapletISplice b) -> Handler b v a -> Handler b v a
    withSplices = SnapletLens (Snaplet b) (Heist b)
    -> Splices (SnapletISplice b) -> Handler b v a -> Handler b v a
    forall b v a.
    SnapletLens (Snaplet b) (Heist b)
    -> Splices (SnapletISplice b) -> Handler b v a -> Handler b v a
    Unclassed.withSplices' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens

    ------------------------------------------------------------------------------
    -- | Runs a handler with a modified 'HeistState'.  You might want to use
    -- this if you had a set of splices which were customised for a specific
    -- action.  To do that you would do:
    --
    -- > heistLocal (bindSplices mySplices) handlerThatNeedsSplices
    heistLocal :: HasHeist b
               => (HeistState (Handler b b) -> HeistState (Handler b b))
                   -- ^ HeistState modifying function
               -> Handler b v a
                   -- ^ Handler to run
               -> Handler b v a
    heistLocal :: (HeistState (Handler b b) -> HeistState (Handler b b))
    -> Handler b v a -> Handler b v a
    heistLocal = SnapletLens (Snaplet b) (Heist b)
    -> (HeistState (Handler b b) -> HeistState (Handler b b))
    -> Handler b v a
    -> Handler b v a
    forall b v a.
    SnapletLens (Snaplet b) (Heist b)
    -> (HeistState (Handler b b) -> HeistState (Handler b b))
    -> Handler b v a
    -> Handler b v a
    Unclassed.heistLocal' SnapletLens (Snaplet b) (Heist b)
    forall b. HasHeist b => SnapletLens (Snaplet b) (Heist b)
    heistLens

    -- $spliceSection
    -- The type signature for SnapletHeist uses @(Handler b b)@ as the Heist
    -- snaplet's runtime monad.  This means that your splices must use the
    -- top-level snaplet's @Handler b b@ monad.  The reasons for this are beyond
    -- the scope of this discussion, but the result is that 'lift' inside a splice
    -- only works with @Handler b b@ actions.  When you're writing your own
    -- snaplets using some snaplet-specific monad @Handler b v@ you still have to
    -- use @Handler b b@ for your splices.  If the splices need any of the context
    -- provided by the @v@, you must pass it in as a parameter to the splice
    -- function.