-- |
-- Module      :  Acme.Grawlix
-- Description :  More readable names for commonly used symbols
-- Copyright   :  Joshua Simmons 2015
-- License     :  BSD3
--
-- Maintainer  :  joshua.simmons@emptypath.com
-- Stability   :  experimental
--
-- More readable names for commonly used symbols.
--
module Acme.Grawlix where

import           Data.List ((\\))
import           Control.Applicative (Alternative, (<|>), (<**>))
import           Data.Monoid ((<>))
import           Control.Monad ((>=>), (<=<))

import           Control.Applicative ( (<$>), (<*>), (<$), (<*), (*>)
                                     , Applicative)
import           Data.Monoid (Monoid)

-- * List

-- | An alias for the type '[]'
type List = []

-- | An alias for '[]'
emptyList :: List a
emptyList = []

-- | An alias for ':'
cons :: a -> List a -> List a
cons = (:)

-- | An alias for '++'
append :: List a -> List a -> List a
append = (++)

-- | An alias for '!!'
index :: List a -> Int -> a
index = (!!)

-- | An alias for '\\'
difference :: Eq a => List a -> List a -> List a
difference = (\\)

-- * Function

-- | An alias for '$'
apply :: (a -> b) -> a -> b
apply = ($)

-- | An alias for '.'
dot :: (b -> c) -> (a -> b) -> a -> c
dot = (.)

-- * Functor

-- | An alias for '<$>'
fmap :: Functor f => (a -> b) -> f a -> f b
fmap = (<$>)

-- | An alias for '<$'
constMap :: Functor f => a -> f b -> f a
constMap = (<$)

-- * Applicative

-- | An alias for '<*>'
ap :: Applicative f => f (a -> b) -> f a -> f b
ap = (<*>)

-- | An alias for '<*'
leftAp :: Applicative f => f a -> f b -> f a
leftAp = (<*)

-- | An alias for '*>'
rightAp :: Applicative f => f a -> f b -> f b
rightAp = (*>)

-- | An alias for '<**>'
flipAp :: Applicative f => f a -> f (a -> b) -> f b
flipAp = (<**>)

-- * Alternative

-- | An alias for '<|>'
orElse :: Alternative f => f a -> f a -> f a
orElse = (<|>)

-- * Monoid

-- | An alias for '<>'
mappend :: Monoid m => m -> m -> m
mappend = (<>)

-- * Monad

-- | An alias for '>>='
bind :: Monad m => m a -> (a -> m b) -> m b
bind = (>>=)

-- | An alias for '>>'
andThen :: Monad m => m a -> m b -> m b
andThen = (>>)

-- | An alias for '=<<'
flipBind :: Monad m => (a -> m b) -> m a -> m b
flipBind = (=<<)

-- | An alias for '>=>'
kleisliCompose :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
kleisliCompose = (>=>)

-- | An alias for '<=<'
flipKleisliCompose :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
flipKleisliCompose = (<=<)

-- * Tuple

-- | An alias for the type '()'
type Unit = ()

-- | An alias for the value '()', of type 'Unit'
unit :: Unit
unit = ()

-- | An alias for a tuple of zero elements
type ZeroTuple = Unit

-- | An alias for a tuple of two elements
type TwoTuple a b = (a, b)

-- | An alias for a tuple of three elements
type ThreeTuple a b c = (a, b, c)

-- | An alias for a tuple of four elements
type FourTuple a b c d = (a, b, c, d)

-- | An alias for a tuple of five elements
type FiveTuple a b c d e = (a, b, c, d, e)

-- | An alias for a tuple of six elements
type SixTuple a b c d e f = (a, b, c, d, e, f)

-- | An alias for a tuple of seven elements
type SevenTuple a b c d e f g = (a, b, c, d, e, f, g)

-- | An alias for a tuple of eight elements
type EightTuple a b c d e f g h = (a, b, c, d, e, f, g, h)

-- | An alias for a tuple of nine elements
type NineTuple a b c d e f g h i = (a, b, c, d, e, f, g, h, i)

-- | An alias for a tuple of ten elements
type TenTuple a b c d e f g h i j= (a, b, c, d, e, f, g, h, i, j)