module Control.Block (
  -- * Functor
  (<$>),
  (<&>),
  fmap,
  imap,
  change,
  ichange,

  -- * Foldable
  foldMap,
  ifoldMap,
  reduce,
  reduceL,
  reduceR,
  ireduce,
  ifor_,
  itraverse_,

  -- * Traversable
  traverse,
  itraverse,
  for,
  ifor,

  -- * Monad
  bind,
  ibind,
) where

import Control.Monad (join)
import Data.Foldable (foldl')
import Data.Foldable.WithIndex (FoldableWithIndex (ifoldMap), ifor_, itraverse_)
import Data.Functor ((<&>))
import Data.Functor.WithIndex (FunctorWithIndex (imap))
import Data.Traversable (for)
import Data.Traversable.WithIndex (TraversableWithIndex (itraverse), ifor)

change :: (Functor f) => f x -> (x -> y) -> f y
change :: forall (f :: * -> *) x y. Functor f => f x -> (x -> y) -> f y
change = forall (f :: * -> *) x y. Functor f => f x -> (x -> y) -> f y
(<&>)

ichange :: (FunctorWithIndex i f) => f x -> (i -> x -> y) -> f y
ichange :: forall i (f :: * -> *) x y.
FunctorWithIndex i f =>
f x -> (i -> x -> y) -> f y
ichange = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall i (f :: * -> *) a b.
FunctorWithIndex i f =>
(i -> a -> b) -> f a -> f b
imap

-- reduce1 :: (Foldable1 t, Semigroup s) => t x -> (x -> s) -> s
-- reduce1 = flip foldMap1

reduce :: (Foldable t, Monoid m) => t x -> (x -> m) -> m
reduce :: forall (t :: * -> *) m x.
(Foldable t, Monoid m) =>
t x -> (x -> m) -> m
reduce = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap

ireduce :: (FoldableWithIndex i t, Monoid m) => t x -> (i -> x -> m) -> m
ireduce :: forall i (t :: * -> *) m x.
(FoldableWithIndex i t, Monoid m) =>
t x -> (i -> x -> m) -> m
ireduce = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall i (f :: * -> *) m a.
(FoldableWithIndex i f, Monoid m) =>
(i -> a -> m) -> f a -> m
ifoldMap

reduceL :: (Foldable t) => y -> t x -> (y -> x -> y) -> y
reduceL :: forall (t :: * -> *) y x.
Foldable t =>
y -> t x -> (y -> x -> y) -> y
reduceL = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'

reduceR :: (Foldable t) => y -> t x -> (x -> y -> y) -> y
reduceR :: forall (t :: * -> *) y x.
Foldable t =>
y -> t x -> (x -> y -> y) -> y
reduceR = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr

bind :: (Monad f) => f x -> (x -> f y) -> f y
bind :: forall (f :: * -> *) x y. Monad f => f x -> (x -> f y) -> f y
bind = forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
(>>=)

ibind :: (FunctorWithIndex i f, Monad f) => f x -> (i -> x -> f y) -> f y
ibind :: forall i (f :: * -> *) x y.
(FunctorWithIndex i f, Monad f) =>
f x -> (i -> x -> f y) -> f y
ibind = (forall (m :: * -> *) a. Monad m => m (m a) -> m a
join .) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i (f :: * -> *) x y.
FunctorWithIndex i f =>
f x -> (i -> x -> y) -> f y
ichange