{-# LANGUAGE TypeOperators #-}

-- | First-class type families
--
-- For example, here is a regular type family:
--
-- @
-- type family   FromMaybe (a :: k) (m :: Maybe k) :: k
-- type instance FromMaybe a 'Nothing  = a
-- type instance FromMaybe a ('Just b) = b
-- @
--
-- With @Fcf@, it translates to a @data@ declaration:
--
-- @
-- data FromMaybe :: k -> Maybe k -> 'Exp' k
-- type instance 'Eval' (FromMaybe a 'Nothing)  = a
-- type instance 'Eval' (FromMaybe a ('Just b)) = b
-- @
--
-- - Fcfs can be higher-order.
-- - The kind constructor 'Exp' is a monad: there's @('=<<')@ and 'Pure'.
--
-- Essential language extensions for "Fcf":
--
-- > {-# LANGUAGE
-- >     DataKinds,
-- >     PolyKinds,
-- >     TypeFamilies,
-- >     TypeOperators,
-- >     UndecidableInstances #-}

module Fcf
  ( -- * First-class type families

    Exp
  , Eval
  , type (@@)

    -- ** Functional combinators

  , Pure
  , Pure1
  , Pure2
  , Pure3
  , Pure4
  , Pure5
  , Pure6
  , Pure7
  , Pure8
  , Pure9
  , type (=<<)
  , type (>>=)
  , type (<=<)
  , LiftM
  , LiftM2
  , LiftM3
  , Join
  , type (<$>)
  , type (<*>)
  , Flip
  , ConstFn
  , type ($)

    -- * Operations on common types

    -- ** Pairs

  , Uncurry
  , Fst
  , Snd
  , type (***)

    -- ** Either

  , UnEither
  , IsLeft
  , IsRight

    -- ** Maybe

  , UnMaybe
  , FromMaybe
  , IsNothing
  , IsJust

    -- ** Lists

  , type (++)
  , Head
  , Last
  , Tail
  , Cons
  , Snoc
  , Cons2
  , Init
  , Uncons
  , Unsnoc
  , Singleton
  , Null
  , Length
  , Reverse
  , Intersperse
  , Intercalate
  , Foldr
  , UnList
  , Concat
  , ConcatMap
  , Unfoldr
  , Replicate
  , Take
  , Drop
  , SplitAt
  , TakeWhile
  , DropWhile
  , Span
  , Break
  , Tails
  , IsPrefixOf
  , IsSuffixOf
  , IsInfixOf
  , Elem
  , Lookup
  , Find
  , Filter
  , Partition
  , FindIndex
  , SetIndex
  , ZipWith
  , Zip
  , Unzip

    -- ** Bool

  , UnBool
  , type (||)
  , type (&&)
  , Not

    -- ** Case splitting

  , Case
  , Match()
  , type (-->)
  , Is
  , Any
  , Else

    -- ** Nat

  , type (+)
  , type (-)
  , type (Fcf.Data.Nat.*)
  , type (^)
  , type (<=)
  , type (>=)
  , type (<)
  , type (>)

    -- * Overloaded operations

  , Map
  , Bimap

    -- * Miscellaneous

  , Error
  , Constraints
  , TyEq
  , Stuck
  , IsBool(_If)
  , If
  , Assert
  , AssertNot

  ) where

import Fcf.Core
import Fcf.Combinators
import Fcf.Data.Bool
import Fcf.Data.Common
import Fcf.Data.List
import Fcf.Data.Nat
import Fcf.Class.Functor
import Fcf.Class.Bifunctor
import Fcf.Utils
