{-# LANGUAGE FlexibleInstances      #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses  #-}
module Control.Monad.Loop
  ( for
  , while
  , With(..)
  , with_
  , withi_
  , withWhile_
  , withWhilei_
  , quit
  , cease
  )
  where

-- This library provides a simple dsl that mimics imperative loop.

-- import           Control.Monad.Loop.Class    (With (..))
import           Control.Monad.Loop.Internal (cease, for, quit, while,
                                              withWhile_, withWhilei_, with_,
                                              withi_)

import           Control.Monad.Except        (ExceptT)
import           Control.Monad.Loop.Internal (Loop)


class With m ret param where
  with :: Loop m ret -> (param -> ExceptT () m ()) -> m ()

instance (Monad m, Traversable t, Integral n) => With m (t a, a -> Bool) (n, a) where
    with :: Loop m (t a, a -> Bool) -> ((n, a) -> ExceptT () m ()) -> m ()
with = Loop m (t a, a -> Bool) -> ((n, a) -> ExceptT () m ()) -> m ()
forall (t :: * -> *) (m :: * -> *) n a.
(Traversable t, Monad m, Integral n) =>
Loop m (t a, a -> Bool) -> ((n, a) -> ExceptT () m ()) -> m ()
withWhilei_

instance (Monad m, Traversable t) => With m (t a, a -> Bool) a where
    with :: Loop m (t a, a -> Bool) -> (a -> ExceptT () m ()) -> m ()
with = Loop m (t a, a -> Bool) -> (a -> ExceptT () m ()) -> m ()
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
Loop m (t a, a -> Bool) -> (a -> ExceptT () m ()) -> m ()
withWhile_

instance (Monad m, Traversable t, Integral n) => With m (t a) (n, a) where
    with :: Loop m (t a) -> ((n, a) -> ExceptT () m ()) -> m ()
with = Loop m (t a) -> ((n, a) -> ExceptT () m ()) -> m ()
forall (t :: * -> *) (m :: * -> *) n a.
(Traversable t, Monad m, Integral n) =>
Loop m (t a) -> ((n, a) -> ExceptT () m ()) -> m ()
withi_

instance (Monad m, Traversable t) => With m (t a) a where
    with :: Loop m (t a) -> (a -> ExceptT () m ()) -> m ()
with = Loop m (t a) -> (a -> ExceptT () m ()) -> m ()
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
Loop m (t a) -> (a -> ExceptT () m ()) -> m ()
with_