    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE Trustworthy #-}
    -----------------------------------------------------------------------------
    -- |
    -- Copyright   :  (C) 2011-2015 Edward Kmett
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
    -- Stability   :  provisional
    -- Portability :  portable
    --
    ----------------------------------------------------------------------------
    module Data.Functor.Bind (
      -- * Functors
        Functor(..)
      , (<$>)     -- :: Functor f => (a -> b) -> f a -> f b
      , ( $>)     -- :: Functor f => f a -> b -> f b
      -- * Applyable functors
      , Apply(..)
      , (<..>)    -- :: Apply w => w a -> w (a -> b) -> w b
      , liftF3    -- :: Apply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d
      -- * Wrappers
      , WrappedApplicative(..)
      , MaybeApply(..)
      -- * Bindable functors
      , Bind(..)
      , gbind
      , (-<<)
      , (-<-)
      , (->-)
      , apDefault
      , returning
      ) where

    import Data.Functor.Apply
    import Data.Functor.Bind.Class
    import GHC.Generics

    -- | Generic '(>>-)'. Caveats:
    --
    --   1. Will not compile if @m@ is a sum type.
    --   2. Will not compile if @m@ contains fields that do not mention its type variable.
    --   3. Will not compile if @m@ contains fields where the type variable appears underneath the composition of type constructors (e.g., @f (g a)@).
    --   4. May do redundant work, due to the nature of the 'Bind' instance for (':*:')
    --
    -- @since 5.3.8
    gbind :: (Generic1 m, Bind (Rep1 m)) => m a -> (a -> m b) -> m b
    gbind :: forall (m :: * -> *) a b.
    (Generic1 m, Bind (Rep1 m)) =>
    m a -> (a -> m b) -> m b
    gbind m a
    m a -> m b
    f = Rep1 m b -> m b
    forall a. Rep1 m a -> m a
    forall k (f :: k -> *) (a :: k). Generic1 f => Rep1 f a -> f a
    to1 (Rep1 m b -> m b) -> Rep1 m b -> m b
    forall a b. (a -> b) -> a -> b
    $ m a -> Rep1 m a
    forall a. m a -> Rep1 m a
    forall k (f :: k -> *) (a :: k). Generic1 f => f a -> Rep1 f a
    from1 m a
    m Rep1 m a -> (a -> Rep1 m b) -> Rep1 m b
    forall a b. Rep1 m a -> (a -> Rep1 m b) -> Rep1 m b
    forall (m :: * -> *) a b. Bind m => m a -> (a -> m b) -> m b
    >>- (\a
    a -> m b -> Rep1 m b
    forall a. m a -> Rep1 m a
    forall k (f :: k -> *) (a :: k). Generic1 f => f a -> Rep1 f a
    from1 (m b -> Rep1 m b) -> m b -> Rep1 m b
    forall a b. (a -> b) -> a -> b
    $ a -> m b
    f a
    a)

    infixr 1 -<<, -<-, ->-

    (-<<) :: Bind m => (a -> m b) -> m a -> m b
    -<< :: forall (m :: * -> *) a b. Bind m => (a -> m b) -> m a -> m b
    (-<<) = (m a -> (a -> m b) -> m b) -> (a -> m b) -> m a -> m b
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip m a -> (a -> m b) -> m b
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Bind m => m a -> (a -> m b) -> m b
    (>>-)

    (->-) :: Bind m => (a -> m b) -> (b -> m c) -> a -> m c
    a -> m b
    f ->- :: forall (m :: * -> *) a b c.
    Bind m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    ->- b -> m c
    g = \a
    a -> a -> m b
    f a
    a m b -> (b -> m c) -> m c
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Bind m => m a -> (a -> m b) -> m b
    >>- b -> m c
    g

    (-<-) :: Bind m => (b -> m c) -> (a -> m b) -> a -> m c
    b -> m c
    g -<- :: forall (m :: * -> *) b c a.
    Bind m =>
    (b -> m c) -> (a -> m b) -> a -> m c
    -<- a -> m b
    f = \a
    a -> a -> m b
    f a
    a m b -> (b -> m c) -> m c
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Bind m => m a -> (a -> m b) -> m b
    >>- b -> m c
    g