{-# LANGUAGE CPP #-}

#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
-----------------------------------------------------------------------------
-- |
-- 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.Apply (
  -- * Functors
    Functor(..)
  , (<$>)     -- :: Functor f => (a -> b) -> f a -> f b
  , ( $>)     -- :: Functor f => f a -> b -> f b

  -- * Apply - a strong lax semimonoidal endofunctor

  , 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(..)
  , (<.*>)
  , (<*.>)
  ) where

import Data.Functor
import Data.Functor.Bind.Class

infixl 4 <..>

-- | A variant of '<.>' with the arguments reversed.
(<..>) :: Apply w => w a -> w (a -> b) -> w b
<..> :: forall (w :: * -> *) a b. Apply w => w a -> w (a -> b) -> w b
(<..>) = (a -> (a -> b) -> b) -> w a -> w (a -> b) -> w b
forall a b c. (a -> b -> c) -> w a -> w b -> w c
forall (f :: * -> *) a b c.
Apply f =>
(a -> b -> c) -> f a -> f b -> f c
liftF2 (((a -> b) -> a -> b) -> a -> (a -> b) -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> b) -> a -> b
forall a. a -> a
id)
{-# INLINE (<..>) #-}


-- | Lift a ternary function into a comonad with zipping
liftF3 :: Apply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d
liftF3 :: forall (w :: * -> *) a b c d.
Apply w =>
(a -> b -> c -> d) -> w a -> w b -> w c -> w d
liftF3 a -> b -> c -> d
f w a
a w b
b w c
c = a -> b -> c -> d
f (a -> b -> c -> d) -> w a -> w (b -> c -> d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> w a
a w (b -> c -> d) -> w b -> w (c -> d)
forall a b. w (a -> b) -> w a -> w b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
<.> w b
b w (c -> d) -> w c -> w d
forall a b. w (a -> b) -> w a -> w b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
<.> w c
c
{-# INLINE liftF3 #-}

#if !(MIN_VERSION_base(4,7,0))

infixl 4 $>

-- | Replace the contents of a functor uniformly with a constant value.
($>) :: Functor f => f a -> b -> f b
($>) = flip (<$)

#endif