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