module Control.Morphism (after, to, by, constant, identity, flip, fix, between, (.), ($), (&), (!), (?), (#), (.^.)) where

infixr 9 .
infixr 0 $
infixl 1 &
infixr 2 !
infixr 2 ?

-- | Prefix version of '.'
{-# INLINE after #-}
after :: (b -> c) -> (a -> b) -> a -> c
after f g = \x -> f (g x)

-- | Prefix version of '$'
{-# INLINE to #-}
to :: (a -> b) -> a -> b
to f x = f x

-- | Prefix version of '&'
{-# INLINE by #-}
by :: a -> (a -> b) -> b
by x f = f x

-- | Prefix version of '!'
{-# INLINE flip #-}
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = f y x

-- | Prefix version of '?'
{-# INLINE constant #-}
constant :: a -> b -> a
constant x y = x

-- | Prefix version of '#'
fix :: (a -> a) -> a
fix f = let x = f x in x

-- | The most trivial function
{-# INLINE identity #-}
identity :: a -> a
identity x = x

-- | Prefix version of '.^.'
{-# INLINE between #-}
between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
between f g = (f .) . (. g)

-- | Infix version of 'constant'
{-# INLINE (?) #-}
(?) = constant

-- | Infix version of 'after'
{-# INLINE (.) #-}
(.) = after

-- | Infix version of 'to'
{-# INLINE ($) #-}
($) = to

-- | Infix version of 'by'
{-# INLINE (&) #-}
(&) = by

-- | Infix version of 'flip'
{-# INLINE (!) #-}
(!) = flip

-- | Infix version of 'fix'
(#) = fix

-- | Infix version of 'between'
(.^.) = between