content: {-# LANGUAGE Trustworthy #-}
  {-# LANGUAGE NoImplicitPrelude #-}
  
  -----------------------------------------------------------------------------
  -- |
  -- Module      :  GHC.Internal.Data.Functor
  -- Copyright   :  (c) The University of Glasgow 2001
  -- License     :  BSD-style (see the file libraries/base/LICENSE)
  --
  -- Maintainer  :  libraries@haskell.org
  -- Stability   :  provisional
  -- Portability :  portable
  --
  --
  -- A type @f@ is a Functor if it provides a function @fmap@ which, given any types @a@ and @b@,
  -- lets you apply any function of type @(a -> b)@ to turn an @f a@ into an @f b@, preserving the
  -- structure of @f@.
  --
  -- ==== __Examples__
  --
  --  >>> fmap show (Just 1)  --  (a   -> b)      -> f a       -> f b
  --  Just "1"                --  (Int -> String) -> Maybe Int -> Maybe String
  --
  --  >>> fmap show Nothing   --  (a   -> b)      -> f a       -> f b
  --  Nothing                 --  (Int -> String) -> Maybe Int -> Maybe String
  --
  --  >>> fmap show [1,2,3]   --  (a   -> b)      -> f a       -> f b
  --  ["1","2","3"]           --  (Int -> String) -> [Int]     -> [String]
  --
  --  >>> fmap show []        --  (a   -> b)      -> f a       -> f b
  --  []                      --  (Int -> String) -> [Int]     -> [String]
  --
  -- The 'fmap' function is also available as the infix operator '<$>':
  --
  --  >>> fmap show (Just 1) --  (Int -> String) -> Maybe Int -> Maybe String
  --  Just "1"
  --
  --  >>> show <$> (Just 1)  --  (Int -> String) -> Maybe Int -> Maybe String
  --  Just "1"
  
  module GHC.Internal.Data.Functor
      (
        Functor(..),
        ($>),
        (<$>),
        (<&>),
        unzip,
        void,
      ) where
  
  import GHC.Internal.Base ( Functor(..), flip )
  import GHC.Internal.Data.Tuple ( fst, snd )
  
  -- $setup
  -- Allow the use of Prelude in doctests.
  -- >>> import Prelude hiding ((<$>))
  
  infixl 4 <$>
  
  -- | An infix synonym for 'fmap'.
  --
  -- The name of this operator is an allusion to 'Prelude.$'.
  -- Note the similarities between their types:
  --
  -- >  ($)  ::              (a -> b) ->   a ->   b
  -- > (<$>) :: Functor f => (a -> b) -> f a -> f b
  --
  -- Whereas 'Prelude.$' is function application, '<$>' is function
  -- application lifted over a 'Functor'.
  --
  -- ==== __Examples__
  --
  -- Convert from a @'Data.Maybe.Maybe' 'Data.Int.Int'@ to a @'Data.Maybe.Maybe'
  -- 'Data.String.String'@ using 'Prelude.show':
  --
  -- >>> show <$> Nothing
  -- Nothing
  --
  -- >>> show <$> Just 3
  -- Just "3"
  --
  -- Convert from an @'Data.Either.Either' 'Data.Int.Int' 'Data.Int.Int'@ to an
  -- @'Data.Either.Either' 'Data.Int.Int'@ 'Data.String.String' using 'Prelude.show':
  --
  -- >>> show <$> Left 17
  -- Left 17
  --
  -- >>> show <$> Right 17
  -- Right "17"
  --
  -- Double each element of a list:
  --
  -- >>> (*2) <$> [1,2,3]
  -- [2,4,6]
  --
  -- Apply 'Prelude.even' to the second element of a pair:
  --
  -- >>> even <$> (2,2)
  -- (2,True)
  --
  (<$>) :: Functor f => (a -> b) -> f a -> f b
  (<$>) = fmap
  
  infixl 1 <&>
  
  -- | Flipped version of '<$>'.
  --
  -- @
  -- ('<&>') = 'flip' 'fmap'
  -- @
  --
  -- @since base-4.11.0.0
  --
  -- ==== __Examples__
  -- Apply @(+1)@ to a list, a 'Data.Maybe.Just' and a 'Data.Either.Right':
  --
  -- >>> Just 2 <&> (+1)
  -- Just 3
  --
  -- >>> [1,2,3] <&> (+1)
  -- [2,3,4]
  --
  -- >>> Right 3 <&> (+1)
  -- Right 4
  --
  (<&>) :: Functor f => f a -> (a -> b) -> f b
  as <&> f = f <$> as
  
  infixl 4 $>
  
  -- | Flipped version of '<$'.
  --
  -- @since base-4.7.0.0
  --
  -- ==== __Examples__
  --
  -- Replace the contents of a @'Data.Maybe.Maybe' 'Data.Int.Int'@ with a constant
  -- 'Data.String.String':
  --
  -- >>> Nothing $> "foo"
  -- Nothing
  --
  -- >>> Just 90210 $> "foo"
  -- Just "foo"
  --
  -- Replace the contents of an @'Data.Either.Either' 'Data.Int.Int' 'Data.Int.Int'@
  -- with a constant 'Data.String.String', resulting in an @'Data.Either.Either'
  -- 'Data.Int.Int' 'Data.String.String'@:
  --
  -- >>> Left 8675309 $> "foo"
  -- Left 8675309
  --
  -- >>> Right 8675309 $> "foo"
  -- Right "foo"
  --
  -- Replace each element of a list with a constant 'Data.String.String':
  --
  -- >>> [1,2,3] $> "foo"
  -- ["foo","foo","foo"]
  --
  -- Replace the second element of a pair with a constant 'Data.String.String':
  --
  -- >>> (1,2) $> "foo"
  -- (1,"foo")
  --
  ($>) :: Functor f => f a -> b -> f b
  ($>) = flip (<$)
  
  -- | Generalization of @Data.List.@'GHC.Internal.Data.List.unzip'.
  --
  -- ==== __Examples__
  --
  -- >>> unzip (Just ("Hello", "World"))
  -- (Just "Hello",Just "World")
  --
  -- >>> unzip [("I", "love"), ("really", "haskell")]
  -- (["I","really"],["love","haskell"])
  --
  -- @since base-4.19.0.0
  unzip :: Functor f => f (a, b) -> (f a, f b)
  unzip xs = (fst <$> xs, snd <$> xs)
  
  -- | @'void' value@ discards or ignores the result of evaluation, such
  -- as the return value of an 'System.IO.IO' action.
  --
  -- ==== __Examples__
  --
  -- Replace the contents of a @'Data.Maybe.Maybe' 'Data.Int.Int'@ with unit:
  --
  -- >>> void Nothing
  -- Nothing
  --
  -- >>> void (Just 3)
  -- Just ()
  --
  -- Replace the contents of an @'Data.Either.Either' 'Data.Int.Int' 'Data.Int.Int'@
  -- with unit, resulting in an @'Data.Either.Either' 'Data.Int.Int' '()'@:
  --
  -- >>> void (Left 8675309)
  -- Left 8675309
  --
  -- >>> void (Right 8675309)
  -- Right ()
  --
  -- Replace every element of a list with unit:
  --
  -- >>> void [1,2,3]
  -- [(),(),()]
  --
  -- Replace the second element of a pair with unit:
  --
  -- >>> void (1,2)
  -- (1,())
  --
  -- Discard the result of an 'System.IO.IO' action:
  --
  -- >>> mapM print [1,2]
  -- 1
  -- 2
  -- [(),()]
  --
  -- >>> void $ mapM print [1,2]
  -- 1
  -- 2
  --
  void :: Functor f => f a -> f ()
  void x = () <$ x
  