content: module Numeric.Partial.Semigroup
    ( PartialSemigroup(..)
    ) where
  
  import Control.Applicative
  import Data.Word
  import Data.Int
  import Numeric.Natural
  
  class PartialSemigroup a where
    padd :: a -> a -> Maybe a
  
  paddNum :: Num a => a -> a -> Maybe a
  paddNum a b = Just (a + b)
  
  
  instance PartialSemigroup Int where
    padd = paddNum
  
  instance PartialSemigroup Integer where
    padd = paddNum
  
  instance PartialSemigroup Natural where
    padd = paddNum
  
  instance PartialSemigroup Int8 where
    padd = paddNum
  
  instance PartialSemigroup Int16 where
    padd = paddNum
  
  instance PartialSemigroup Int32 where
    padd = paddNum
  
  instance PartialSemigroup Int64 where
    padd = paddNum
  
  instance PartialSemigroup Word where
    padd = paddNum
  
  instance PartialSemigroup Word8 where
    padd = paddNum
  
  instance PartialSemigroup Word16 where
    padd = paddNum
  
  instance PartialSemigroup Word32 where
    padd = paddNum
  
  instance PartialSemigroup Word64 where
    padd = paddNum
  
  instance PartialSemigroup a => PartialSemigroup (Maybe a) where
    padd ma mb = Just $ do
     a <- ma
     b <- mb
     padd a b
  
  instance PartialSemigroup Bool where
    padd a b = Just (a || b)
  
  instance PartialSemigroup () where
    padd _ _ = Just ()
  
  instance (PartialSemigroup a, PartialSemigroup b) => PartialSemigroup (a, b) where
    padd (a,b) (i,j) = (,) <$> padd a i <*> padd b j
  
  instance (PartialSemigroup a, PartialSemigroup b, PartialSemigroup c) => PartialSemigroup (a, b, c) where
    padd (a,b,c) (i,j,k) = (,,) <$> padd a i <*> padd b j <*> padd c k
  
  instance (PartialSemigroup a, PartialSemigroup b, PartialSemigroup c, PartialSemigroup d) => PartialSemigroup (a, b, c, d) where
    padd (a,b,c,d) (i,j,k,l) = (,,,) <$> padd a i <*> padd b j <*> padd c k <*> padd d l
  
  instance (PartialSemigroup a, PartialSemigroup b, PartialSemigroup c, PartialSemigroup d, PartialSemigroup e) => PartialSemigroup (a, b, c, d, e) where
    padd (a,b,c,d,e) (i,j,k,l,m) = (,,,,) <$> padd a i <*> padd b j <*> padd c k <*> padd d l <*> padd e m
  
  instance (PartialSemigroup a, PartialSemigroup b) => PartialSemigroup (Either a b) where
    padd (Left a) (Left b) = Left <$> padd a b
    padd (Right a) (Right b) = Right <$> padd a b
    padd _ _ = Nothing
  