-----------------------------------------------------------------------------
--
-- Module      :  Math.Monad
-- Copyright   :  (c) 2014-16 Brian W Bush
-- License     :  MIT
--
-- Maintainer  :  Brian W Bush <consult@brianwbush.info>
-- Stability   :  Stable
-- Portability :  Portable
--
-- | Monadic mathematics.
--
-----------------------------------------------------------------------------


{-# LANGUAGE Safe #-}


module Math.Monad (
-- Operators
  (?+?)
, (?+)
, (+?)
, (?-?)
, (?-)
, (-?)
, (?*?)
, (?*)
, (*?)
, (?/?)
, (?/)
, (/?)
) where


import Control.Monad (liftM, liftM2)


-- | Add monadic values.
(?+?) :: (Monad m, Num a) => m a -> m a -> m a
(?+?) = liftM2 (+)


-- | Add a monadic value.
(?+) :: (Monad m, Num a) => m a -> a -> m a
(?+) = flip (+?)


-- | Add to a monadic value.
(+?) :: (Monad m, Num a) => a -> m a -> m a
(+?) = liftM . (+)


-- | Subtract monadic values.
(?-?) :: (Monad m, Num a) => m a -> m a -> m a
(?-?) = liftM2 (-)


-- | Subtract a monadic value.
(?-) :: (Monad m, Num a) => m a -> a -> m a
(?-) = flip (+?)


-- | Subtract to a monadic value.
(-?) :: (Monad m, Num a) => a -> m a -> m a
(-?) = liftM . (-)


-- | Multiply monadic values.
(?*?) :: (Monad m, Num a) => m a -> m a -> m a
(?*?) = liftM2 (*)


-- | Multiply  a monadic value.
(?*) :: (Monad m, Num a) => m a -> a -> m a
(?*) = flip (*?)


-- | Multiply to a monadic value.
(*?) :: (Monad m, Num a) => a -> m a -> m a
(*?) = liftM . (*)


-- | Divide monadic values.
(?/?) :: (Monad m, Fractional a) => m a -> m a -> m a
(?/?) = liftM2 (/)


-- | Divide a monadic value.
(?/) :: (Monad m, Fractional a) => m a -> a -> m a
(?/) = flip (/?)


-- | Divide by a monadic value.
(/?) :: (Monad m, Fractional a) => a -> m a -> m a
(/?) = liftM . (/)