content: {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}
  module Numeric.Algebra.Idempotent 
    ( Band
    , pow1pBand
    , powBand
    -- * Idempotent algebras
    , IdempotentAlgebra
    , IdempotentCoalgebra
    , IdempotentBialgebra
    ) where
  
  import Numeric.Algebra.Class
  import Numeric.Algebra.Unital
  import Numeric.Natural
  import Data.Set (Set)
  import Data.IntSet (IntSet)
  
  -- | An multiplicative semigroup with idempotent multiplication.
  --
  -- > a * a = a
  class Multiplicative r => Band r
  
  pow1pBand :: r -> Natural -> r
  pow1pBand r _ = r 
  
  powBand :: Unital r => r -> Natural -> r
  powBand _ 0 = one
  powBand r _ = r
  
  instance Band ()
  instance Band Bool
  instance (Band a, Band b) => Band (a,b)
  instance (Band a, Band b, Band c) => Band (a,b,c)
  instance (Band a, Band b, Band c, Band d) => Band (a,b,c,d)
  instance (Band a, Band b, Band c, Band d, Band e) => Band (a,b,c,d,e)
  
  -- idempotent algebra
  class Algebra r a => IdempotentAlgebra r a
  instance (Semiring r, Band r, Ord a) => IdempotentAlgebra r (Set a)
  instance (Semiring r, Band r) => IdempotentAlgebra r IntSet
  instance (Semiring r, Band r) => IdempotentAlgebra r ()
  instance (IdempotentAlgebra r a, IdempotentAlgebra r b) => IdempotentAlgebra r (a,b)
  instance (IdempotentAlgebra r a, IdempotentAlgebra r b, IdempotentAlgebra r c) => IdempotentAlgebra r (a,b,c)
  instance (IdempotentAlgebra r a, IdempotentAlgebra r b, IdempotentAlgebra r c, IdempotentAlgebra r d) => IdempotentAlgebra r (a,b,c,d)
  instance (IdempotentAlgebra r a, IdempotentAlgebra r b, IdempotentAlgebra r c, IdempotentAlgebra r d, IdempotentAlgebra r e) => IdempotentAlgebra r (a,b,c,d,e)
  
  -- idempotent coalgebra
  class Coalgebra r c => IdempotentCoalgebra r c
  instance (Semiring r, Band r, Ord c) => IdempotentCoalgebra r (Set c)
  instance (Semiring r, Band r) => IdempotentCoalgebra r IntSet
  instance (Semiring r, Band r) => IdempotentCoalgebra r ()
  instance (IdempotentCoalgebra r a, IdempotentCoalgebra r b) => IdempotentCoalgebra r (a,b)
  instance (IdempotentCoalgebra r a, IdempotentCoalgebra r b, IdempotentCoalgebra r c) => IdempotentCoalgebra r (a,b,c)
  instance (IdempotentCoalgebra r a, IdempotentCoalgebra r b, IdempotentCoalgebra r c, IdempotentCoalgebra r d) => IdempotentCoalgebra r (a,b,c,d)
  instance (IdempotentCoalgebra r a, IdempotentCoalgebra r b, IdempotentCoalgebra r c, IdempotentCoalgebra r d, IdempotentCoalgebra r e) => IdempotentCoalgebra r (a,b,c,d,e)
  
  -- idempotent bialgebra
  class (Bialgebra r h, IdempotentAlgebra r h, IdempotentCoalgebra r h) => IdempotentBialgebra r h 
  instance (Bialgebra r h, IdempotentAlgebra r h, IdempotentCoalgebra r h) => IdempotentBialgebra r h 
  