-----------------------------------------------------------------------------
-- |
-- Module      :  $header
-- Copyright   :  (c) Laurent P. René de Cotret
-- License     :  MIT-style
-- Maintainer  :  Laurent P. René de Cotret
-- Portability :  portable
--
-- This module contains the definition of 'Index', a sequence of /unique/ and /sorted/
-- keys which can be used to efficient index a 'Data.Series.Series'.
--
-- = Construction
--
-- Constructing an 'Index' can be done from the usual list using `fromList`. Note that 
-- the 'Index' length could be smaller than the input list, due to the requirement that
-- an 'Index' be a sequence of unique keys.  A better way to construct an 'Index' is 
-- to use a 'Data.Set' (`fromSet`)
--
-- For quick INLINABLE definitions of an 'Index', you can also make use of the @OverloadedLists@ extension:
-- 
-- >>> :set -XOverloadedLists
-- >>> let (ix :: Index Int) = [1,2,3,4,5,5,5]
-- >>> ix
-- Index [1,2,3,4,5] 
--
-- Another useful function to construct an 'Index' is `range`. This allows to build an 'Index'
-- from a starting value up to an ending value, with a custom step function. For example,
-- here's an 'Index' with values from 1 to 10, in steps of 3:
--
-- >>> range (+3) (1 :: Int) 10
-- Index [1,4,7,10]
--
-- Note that `range` is a special case of the `unfoldr` function, which is also provided in this module.
--
-- = Set operations
-- 
-- Just like a 'Data.Set', 'Index' supports efficient `member`, `notMember`, `union`, `intersection`, and `difference` operations.
-- Like 'Data.Set', the `Semigroup` and `Monoid` instance of 'Index' are defined using the `union` operation:
--
-- >>> fromList ['a', 'b', 'c'] <> fromList ['b', 'c', 'd']
-- Index "abcd"
--
-- = Mapping
--
-- Because of the restriction that all keys be unique, an 'Index' is not a true `Functor`; you can't use
-- `fmap` to map elements of an index. Instead, you can use the general-purpose function 'map'. If you want
-- to map elements of an 'Index' with a monotonic function (i.e. a function which will not re-order elements and won't
-- create duplicate elements), you can use the 'Data.Series.mapMonotonic' function which operates faster.
--
-- = Indexing
--
-- One of the key operations for 'Data.Series.Series' is to find the integer index of an element in an 'Index'. For this purpose, you
-- can use `lookupIndex`:
--
-- >>> lookupIndex 'b' $ fromList ['a', 'b', 'c']
-- Just 1
-- >>> lookupIndex 'd' $ fromList ['a', 'b', 'c']
-- Nothing

module Data.Series.Index (
    Index,

    -- * Creation and Conversion
    singleton,
    unfoldr,
    range,
    IsIndex(..),
    fromSet,
    fromList,
    fromVector,
    toSet,
    toAscList,
    toAscVector,

    -- * Set-like operations
    null,
    member,
    notMember,
    union,
    intersection,
    difference,
    symmetricDifference,
    contains,
    size,
    take,
    drop,

    -- * Mapping and filtering
    map,
    indexed,
    filter,
    traverse,
    
    -- * Indexing
    lookupIndex,

    -- * Insertion and deletion
    insert,
    delete,
) where

import Data.Series.Index.Definition ( Index, IsIndex(..), singleton, unfoldr, range, fromSet, fromList, fromVector, toSet
                                    , toAscList, toAscVector, null, member, notMember, union, intersection
                                    , difference, symmetricDifference, contains, size, take, drop, map, indexed
                                    , filter, traverse, lookupIndex, insert, delete 
                                    )
import Prelude hiding ( null, take, drop, map, filter, traverse )