{-# LANGUAGE CPP #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Protolude.Functor (
  Functor(fmap),
  ($>),
  (<$),
  (<$>),
  (<<$>>),
  (<&>),
  void,
  foreach,
) where

import Data.Function ((.), flip)
#if MIN_VERSION_base(4,11,0)
import Data.Functor ((<&>))
#endif

#if MIN_VERSION_base(4,7,0)
import Data.Functor (
    Functor(fmap)
  , (<$)
  , ($>)
  , (<$>)
  , void
  )
#else
import Data.Functor (
    Functor(fmap)
  , (<$)
  , (<$>)
  )


infixl 4 $>

($>) :: Functor f => f a -> b -> f b
($>) = flip (<$)

void :: Functor f => f a -> f ()
void x = () <$ x
#endif

infixl 4 <<$>>

(<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
<<$>> :: forall (f :: * -> *) (g :: * -> *) a b.
(Functor f, Functor g) =>
(a -> b) -> f (g a) -> f (g b)
(<<$>>) = (g a -> g b) -> f (g a) -> f (g b)
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((g a -> g b) -> f (g a) -> f (g b))
-> ((a -> b) -> g a -> g b) -> (a -> b) -> f (g a) -> f (g b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> g a -> g b
forall a b. (a -> b) -> g a -> g b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap

foreach :: Functor f => f a -> (a -> b) -> f b
foreach :: forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
foreach = ((a -> b) -> f a -> f b) -> f a -> (a -> b) -> f b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> b) -> f a -> f b
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap

#if !MIN_VERSION_base(4,11,0)
-- | Infix version of foreach.
--
-- '<&>' is to '<$>' what '&' is to '$'.

infixl 1 <&>
(<&>) :: Functor f => f a -> (a -> b) -> f b
(<&>) = foreach
#endif