```-- |Helper functions for functors.
--
--  These operators are designed to make the interoperation between monadic
--  and pure computations more convenient by allowed them to be chained together
--  without peppering the program with superflouos return statements.
--
--  Each function is a pure analogue of a monadic one. The correspondences are
--  as follows:
--  @
--  >\$>   ~  >>=
--  \$>    ~  >>
--  <\$    ~  <<   (re-exported from Data.Functor)
--  <\$<   ~  =<<  (same as Data.Functor.<\$>, but with the precedence of >>=)
--  >=\$>  ~  >=>
--  <\$=<  ~  <=<
--  @
--
-- Lastly, '|>' is left-to-right function composition (flipped version of '\$').
module Data.Functor,
(>\$>),
(\$>),
(<\$<),
(>=\$>),
(<\$=<),
(|>)) where

import Data.Functor ((<\$))

infixl 1 >\$>
infixl 1 \$>
infixr 1 <\$<
infixl 1 >=\$>
infixr 1 <\$=<
infixl 1 |>

-- |Flipped 'fmap' for chaining plain functions after a functor in the following
--  way:
--
-- @
-- readFile '1.txt' >\$> lines >\$> map length >>= print
-- @
--
-- @lines@ and @map length@ are non-monadic functions, but peppering
-- them with returns, as pure '>>=' necessitates, is quite tedious.
--
-- In general:
--
-- @
-- m >>= return . f   is the same as   m >\$> f
-- @
(>\$>) :: Functor f => f a -> (a -> b) -> f b
(>\$>) = flip fmap

-- |Left-associatiative, flipped '\$>'. Corresponds to '>>'
(\$>) :: Functor f => f b -> a -> f a
(\$>) = flip (<\$)

-- |Right-associative infix synonym for 'fmap'.
(<\$<) :: Functor f => (a -> b) -> f a -> f b
(<\$<) = fmap

-- |Application of '>\$>' to Kleisli composition 'Control.Monad.>=>'
--  Use is analogous to that of '>\$>', e.g.
--
--  @
--  f :: FilePath -> IO ()
--  f = (readFile >=\$> lines >=\$> map length >=> print)
--  @
--
--  In general:
--
--  @
--  m >=\$> f   is the same as   m >=> return . f
--  @
(>=\$>) :: Functor f => (a -> f b) -> (b -> c) -> a -> f c
(>=\$>) f g x = f x >\$> g

-- |Flipped version of '>=\$>'.
(<\$=<) :: Functor f => (b -> c) -> (a -> f b) -> a -> f c
(<\$=<) = flip (>=\$>)

-- |Flipped version of '\$'.
(|>) :: a -> (a -> b) -> b
(|>) = flip (\$)
```