module Data.Zero where
import Control.Monad.Fix ( MonadFix )
import Data.Semigroup ( Semigroup(..) )
import GHC.Generics ( Generic )
class (Semigroup a) => Zero a where
zero :: a
zconcat :: [a] -> a
default zconcat :: (Semigroup a) => [a] -> a
zconcat [] = zero
zconcat (x:xs) = foldr (<>) x xs
instance Zero () where
zero = ()
newtype Product a = Product { getProduct :: a }
deriving (Bounded,Eq,Generic,Num,Ord,Read,Show)
instance (Num a) => Semigroup (Product a) where
Product a <> Product b = Product $ a * b
instance (Num a) => Zero (Product a) where
zero = Product 0
newtype Any = Any { getAny :: Bool } deriving (Bounded,Eq,Generic,Ord,Read,Show)
instance Semigroup Any where
Any a <> Any b = Any $ a || b
instance Zero Any where
zero = Any True
newtype All = All { getAll :: Bool} deriving (Bounded,Eq,Generic,Ord,Read,Show)
instance Semigroup All where
All a <> All b = All $ a && b
instance Zero All where
zero = All False
newtype Success a = Success { getSuccess :: Maybe a }
deriving (Applicative,Eq,Foldable,Functor,Monad,MonadFix,Ord,Traversable,Read,Show)
instance (Semigroup a) => Semigroup (Success a) where
Success (Just a) <> Success (Just b) = Success . Just $ a <> b
_ <> _ = zero
instance (Semigroup a) => Zero (Success a) where
zero = Success Nothing
success :: a -> Success a
success = Success . Just
failure :: Success a
failure = Success Nothing