    --------------------------------------------------------------------------------
    -- |
    -- Module      :  Control.Lens.Combinators
    -- Copyright   :  (C) 2012-13 Edward Kmett
    -- License     :  BSD-style (see the file LICENSE)
    -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- These are general purpose combinators that provide utility for non-lens code
    -------------------------------------------------------------------------------
    module Control.Lens.Combinators
      ( (&)
      , (<&>)
      , (??)
      ) where

    import Data.Functor ((<$>))

    -- $setup
    -- >>> import Control.Lens
    -- >>> import Control.Monad.State
    -- >>> import Debug.SimpleReflect.Expr
    -- >>> import Debug.SimpleReflect.Vars as Vars hiding (f)
    -- >>> :set -XNoOverloadedStrings
    -- >>> let f :: Expr -> Expr; f = Debug.SimpleReflect.Vars.f

    infixl 1 &, <&>, ??

    -- | Passes the result of the left side to the function on the right side (forward pipe operator).
    --
    -- This is the flipped version of ('$'), which is more common in languages like F# as (@|>@) where it is needed
    -- for inference. Here it is supplied for notational convenience and given a precedence that allows it
    -- to be nested inside uses of ('$').
    --
    -- >>> a & f
    -- f a
    --
    -- >>> "hello" & length & succ
    -- 6
    --
    -- This combinator is commonly used when applying multiple 'Control.Lens.Lens.Lens' operations in sequence.
    --
    -- >>> ("hello","world") & _1.element 0 .~ 'j' & _1.element 4 .~ 'y'
    -- ("jelly","world")
    --
    -- This reads somewhat similar to:
    --
    -- >>> flip execState ("hello","world") $ do _1.element 0 .= 'j'; _1.element 4 .= 'y'
    -- ("jelly","world")
    (&) :: a -> (a -> b) -> b
    a & f = f a
    {-# INLINE (&) #-}

    -- | Infix flipped 'fmap'.
    --
    -- @
    -- ('<&>') = 'flip' 'fmap'
    -- @
    (<&>) :: Functor f => f a -> (a -> b) -> f b
    as <&> f = f <$> as
    {-# INLINE (<&>) #-}

    -- | This is convenient to 'flip' argument order of composite functions.
    --
    -- >>> over _2 ?? ("hello","world") $ length
    -- ("hello",5)
    --
    -- >>> over ?? length ?? ("hello","world") $ _2
    -- ("hello",5)
    (??) :: Functor f => f (a -> b) -> a -> f b
    fab ?? a = fmap ($ a) fab
    {-# INLINE (??) #-}