{-# OPTIONS_GHC -Wno-orphans #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LinearTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE StandaloneDeriving #-}

-- | This module provides linear versions of 'Monoid'.
--
-- To learn about how these classic monoids work, go to this school of haskell
-- [post](https://www.schoolofhaskell.com/user/mgsloan/monoids-tour).
module Data.Monoid.Linear.Internal.Monoid
  ( -- * Monoid operations
    Monoid(..)
  , mconcat
  )
  where

import Prelude.Linear.Internal
import Data.Monoid.Linear.Internal.Semigroup
import GHC.Types hiding (Any)
import qualified Prelude

-- | A linear monoid is a linear semigroup with an identity on the binary
-- operation.
class (Semigroup a, Prelude.Monoid a) => Monoid a where
  {-# MINIMAL #-}
  mempty :: a
  mempty = a
forall a. Monoid a => a
Prelude.mempty
  -- convenience redefine

mconcat :: Monoid a => [a] %1-> a
mconcat :: forall a. Monoid a => [a] %1 -> a
mconcat ([a]
xs' :: [a]) = a %1 -> [a] %1 -> a
go a
forall a. Monoid a => a
mempty [a]
xs'
  where
    go :: a %1-> [a] %1-> a
    go :: a %1 -> [a] %1 -> a
go a
acc [] = a
acc
    go a
acc (a
x:[a]
xs) = a %1 -> [a] %1 -> a
go (a
acc a %1 -> a %1 -> a
forall a. Semigroup a => a %1 -> a %1 -> a
<> a
x) [a]
xs

---------------
-- Instances --
---------------

instance Prelude.Monoid (Endo a) where
  mempty :: Endo a
mempty = (a %1 -> a) -> Endo a
forall a. (a %1 -> a) -> Endo a
Endo a %1 -> a
forall a. a %1 -> a
id
instance Monoid (Endo a)

instance (Monoid a, Monoid b) => Monoid (a,b)

instance Monoid a => Monoid (Dual a)

instance Monoid Ordering where
    mempty :: Ordering
mempty = Ordering
EQ