-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Functor.Indexed
-- Copyright   :  (C) 2008 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  Reiner Pope <reiner.pope@gmail.com>
-- Stability   :  experimental
-- Portability :  portable
--
----------------------------------------------------------------------------
module Data.Functor.Indexed
  ( IxFunctor(..)
  , IxCopointed(..)
  , IxPointed(..)
  , IxApplicative(..)
  , (<<$>>), (<<*>>), (<<*), (*>>)
  ) where

class IxFunctor f where
  imap :: (a -> b) -> f j k a -> f j k b

-- | Infix alias of 'imap'.  Or, ('<$>') for 'IxFunctor'.  Should be
-- interchangeable with ('<$>'), but requires 'IxFunctor' constraints instead
-- of (possibly many) 'Functor' constraints.
infixl 4 <<$>>
(<<$>>) :: IxFunctor f => (a -> b) -> f j k a -> f j k b
<<$>> :: forall {k} {k} (f :: k -> k -> * -> *) a b (j :: k) (k :: k).
IxFunctor f =>
(a -> b) -> f j k a -> f j k b
(<<$>>) = forall {k} {k} (f :: k -> k -> * -> *) a b (j :: k) (k :: k).
IxFunctor f =>
(a -> b) -> f j k a -> f j k b
imap

class IxPointed m => IxApplicative m where
  iap :: m i j (a -> b) -> m j k a -> m i k b

-- | Infix alias of 'iap'.  Or, ('<*>') for 'IxApplicative'.
infixl 4 <<*>>
(<<*>>) :: IxApplicative f => f i j (a -> b) -> f j k a -> f i k b
<<*>> :: forall {k} (f :: k -> k -> * -> *) (i :: k) (j :: k) a b (k :: k).
IxApplicative f =>
f i j (a -> b) -> f j k a -> f i k b
(<<*>>) = forall {k} (m :: k -> k -> * -> *) (i :: k) (j :: k) a b (k :: k).
IxApplicative m =>
m i j (a -> b) -> m j k a -> m i k b
iap

-- | ('Control.Applicative.<*') for 'IxApplicative'.
infixl 4 <<*
(<<*) :: IxApplicative f => f i j a -> f j k b -> f i k a
<<* :: forall {k} (f :: k -> k -> * -> *) (i :: k) (j :: k) a (k :: k) b.
IxApplicative f =>
f i j a -> f j k b -> f i k a
(<<*) f i j a
a f j k b
b = forall {k} {k} (f :: k -> k -> * -> *) a b (j :: k) (k :: k).
IxFunctor f =>
(a -> b) -> f j k a -> f j k b
imap forall a b. a -> b -> a
const f i j a
a forall {k} (f :: k -> k -> * -> *) (i :: k) (j :: k) a b (k :: k).
IxApplicative f =>
f i j (a -> b) -> f j k a -> f i k b
<<*>> f j k b
b

-- | ('Control.Applicative.*>') for 'IxApplicative'.
infixl 4 *>>
(*>>) :: IxApplicative f => f i j a -> f j k b -> f i k b
*>> :: forall {k} (f :: k -> k -> * -> *) (i :: k) (j :: k) a (k :: k) b.
IxApplicative f =>
f i j a -> f j k b -> f i k b
(*>>) f i j a
a f j k b
b = forall {k} {k} (f :: k -> k -> * -> *) a b (j :: k) (k :: k).
IxFunctor f =>
(a -> b) -> f j k a -> f j k b
imap (forall a b. a -> b -> a
const forall a. a -> a
id) f i j a
a forall {k} (f :: k -> k -> * -> *) (i :: k) (j :: k) a b (k :: k).
IxApplicative f =>
f i j (a -> b) -> f j k a -> f i k b
<<*>> f j k b
b

class IxFunctor m => IxPointed m where
  ireturn :: a -> m i i a

class IxFunctor w => IxCopointed w where
  iextract :: w i i a -> a