{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Data.Singletons.Prelude.Monoid (
PMonoid(..), SMonoid(..),
Sing(SDual, sGetDual, SAll, sGetAll, SAny, sGetAny, SSum, sGetSum,
SProduct, sGetProduct, SFirst, sGetFirst, SLast, sGetLast),
GetDual, GetAll, GetAny, GetSum, GetProduct, GetFirst, GetLast,
SDual, SAll, SAny, SSum, SProduct, SFirst, SLast,
MemptySym0,
MappendSym0, MappendSym1, MappendSym2,
MconcatSym0, MconcatSym1,
DualSym0, DualSym1, GetDualSym0, GetDualSym1,
AllSym0, AllSym1, GetAllSym0, GetAllSym1,
AnySym0, AnySym1, GetAnySym0, GetAnySym1,
SumSym0, SumSym1, GetSumSym0, GetSumSym1,
ProductSym0, ProductSym1, GetProductSym0, GetProductSym1,
FirstSym0, FirstSym1, GetFirstSym0, GetFirstSym1,
LastSym0, LastSym1, GetLastSym0, GetLastSym1
) where
import Data.Monoid (First(..), Last(..))
import Data.Ord (Down(..))
import Data.Semigroup hiding (First(..), Last(..))
import Data.Singletons.Prelude.Base
import Data.Singletons.Prelude.Eq
import Data.Singletons.Prelude.Instances
import Data.Singletons.Prelude.Monad.Internal
import Data.Singletons.Prelude.Num
import Data.Singletons.Prelude.Ord
import Data.Singletons.Prelude.Semigroup.Internal hiding
(Sing(SFirst, SLast), SFirst, SLast,
FirstSym0, FirstSym1, FirstSym0KindInference,
LastSym0, LastSym1, LastSym0KindInference,
GetFirst, GetFirstSym0, GetFirstSym1, GetFirstSym0KindInference,
GetLast, GetLastSym0, GetLastSym1, GetLastSym0KindInference)
import Data.Singletons.Prelude.Show
import Data.Singletons.Single
import Data.Singletons.Util
import GHC.TypeLits (Symbol)
$(singletonsOnly [d|
class Semigroup a => Monoid a where
mempty :: a
mappend :: a -> a -> a
mappend = (<>)
mconcat :: [a] -> a
mconcat = foldr mappend mempty
instance Monoid [a] where
mempty = []
instance Monoid b => Monoid (a -> b) where
mempty _ = mempty
instance Monoid () where
mempty = ()
mconcat _ = ()
instance (Monoid a, Monoid b) => Monoid (a,b) where
mempty = (mempty, mempty)
instance (Monoid a, Monoid b, Monoid c) => Monoid (a,b,c) where
mempty = (mempty, mempty, mempty)
instance (Monoid a, Monoid b, Monoid c, Monoid d) => Monoid (a,b,c,d) where
mempty = (mempty, mempty, mempty, mempty)
instance (Monoid a, Monoid b, Monoid c, Monoid d, Monoid e) =>
Monoid (a,b,c,d,e) where
mempty = (mempty, mempty, mempty, mempty, mempty)
instance Monoid Ordering where
mempty = EQ
instance Semigroup a => Monoid (Maybe a) where
mempty = Nothing
instance Monoid Symbol where
mempty = ""
|])
$(genSingletons monoidBasicTypes)
$(showSingInstances monoidBasicTypes)
$(singEqInstances monoidBasicTypes)
$(singDecideInstances monoidBasicTypes)
$(singOrdInstances monoidBasicTypes)
$(singShowInstances monoidBasicTypes)
$(singletonsOnly [d|
instance Monoid a => Monoid (Dual a) where
mempty = Dual mempty
instance Monoid All where
mempty = All True
instance Monoid Any where
mempty = Any False
instance Num a => Monoid (Sum a) where
mempty = Sum 0
instance Num a => Monoid (Product a) where
mempty = Product 1
instance Monoid a => Monoid (Down a) where
mempty = Down mempty
instance Applicative First where
pure = First . pure
First f <*> First x = First (f <*> x)
deriving instance Functor First
instance Monad First where
First a >>= k = First (a >>= \x -> case k x of First y -> y)
instance Semigroup (First a) where
First Nothing <> b = b
a@(First Just{}) <> _ = a
instance Monoid (First a) where
mempty = First Nothing
instance Applicative Last where
pure = Last . pure
Last f <*> Last x = Last (f <*> x)
deriving instance Functor Last
instance Monad Last where
Last a >>= k = Last (a >>= \x -> case k x of Last y -> y)
instance Semigroup (Last a) where
a <> Last Nothing = a
_ <> b@(Last Just {}) = b
instance Monoid (Last a) where
mempty = Last Nothing
|])