{-# LANGUAGE DefaultSignatures #-}
module Algebra.Classes where

import Algebra.Core

class Functor f where
  map :: (a -> b) -> f a -> f b
class (Unit f, Functor f) => Applicative f where
  infixl 2 <*>
  (<*>) :: f (a -> b) -> f a -> f b
  default (<*>) :: Monad f => f (a -> b) -> f a -> f b
  fs <*> xs = fs >>= \f -> map f xs
class Applicative m => Monad m where
  join :: m (m a) -> m a
  join m = m >>= id
  infixl 1 >>=
  (>>=) :: m a -> (a -> m b) -> m b
  ma >>= k = join (map k ma)

-- |The class of all monads that have a fixpoint
class Monad m => MonadFix m where
  mfix :: (a -> m a) -> m a
class MonadTrans t where
  lift :: Monad m => m a -> t m a
  generalize :: Monad m => t Id a -> t m a

class Monad m => MonadState s m | m -> s where
  get :: m s
  put :: s -> m ()
  put = modify . const
  modify :: (s -> s) -> m ()
  modify f = get >>= put . f
class Monad m => MonadReader r m | m -> r where
  ask :: m r
  local :: (r -> r) -> m a -> m a
class (Monad m,Monoid w) => MonadWriter w m | m -> w where
  tell :: w -> m ()
  listen :: m a -> m (w,a)
  censor :: m (a,w -> w) -> m a

class Monad m => MonadList m where
  fork :: [a] -> m a
class Monad m => MonadCont m where
  callCC :: ((a -> m b) -> m a) -> m a
class Monad m => MonadError e m | m -> e where
  throw :: e -> m a
  catch :: (e -> m a) -> m a -> m a