{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Ring.Module
-- Copyright   :  (c) Edward Kmett 2009
-- License     :  BSD-style
-- Maintainer  :  ekmett@gmail.com
-- Stability   :  experimental
-- Portability :  non-portable (MPTCs)
--
-- Left- and right- modules over rings, semirings, and Seminearrings.
-- To avoid a proliferation of classes. These only require that there
-- be an addition and multiplication operation for the 'Ring'
--
-----------------------------------------------------------------------------

module Data.Ring.Module 
    ( module Data.Ring
    , LeftModule
    , (*.)
    , RightModule
    , (.*)
    , Module
    ) where

import Data.Ring
-- import qualified Data.Monoid.Combinators as Monoid

-- | @ (x * y) *. m = x * (y *. m) @
class (Monoid r, Multiplicative r, Monoid m) => LeftModule r m where
    (*.) :: r -> m -> m
    
-- | @ (m .* x) * y = m .* (x * y) @
class (Monoid r, Multiplicative r, Monoid m) => RightModule r m where
    (.*) :: m -> r -> m

-- | @ (x *. m) .* y = x *. (m .* y) @
class (LeftModule r m, RightModule r m) => Module r m 

-- instance Monoid m => LeftModule Int m where i *. m = Monoid.replicate m i 
-- instance Monoid m => RightModule Int m where m .* i = Monoid.replicate m i 
-- instance Monoid m => Module Int m
    
-- instance Monoid m => LeftModule Integer m where i *. m = Monoid.replicate m i 
-- instance Monoid m => RightModule Integer m where m .* i = Monoid.replicate m i 
-- instance Monoid m => Module Integer m