-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Compat.DList
-- Copyright   :  (c) Ben Gamari 2015-2019
-- License     :  BSD3
--
-- Maintainer  :  cabal-dev@haskell.org
-- Stability   :  experimental
-- Portability :  portable
--
-- A very simple difference list.
module Distribution.Compat.DList (
    DList,
    runDList,
    empty,
    singleton,
    fromList,
    toList,
    snoc,
) where

import Prelude ()
import Distribution.Compat.Prelude hiding (toList, empty)

-- | Difference list.
newtype DList a = DList ([a] -> [a])

runDList :: DList a -> [a]
runDList :: forall a. DList a -> [a]
runDList (DList [a] -> [a]
run) = [a] -> [a]
run []

-- | Make 'DList' containing single element.
singleton :: a -> DList a
singleton :: forall a. a -> DList a
singleton a
a = forall a. ([a] -> [a]) -> DList a
DList (a
aforall a. a -> [a] -> [a]
:)

-- | @since 3.4.0.0
empty :: DList a
empty :: forall a. DList a
empty = forall a. ([a] -> [a]) -> DList a
DList forall a. a -> a
id

fromList :: [a] -> DList a
fromList :: forall a. [a] -> DList a
fromList [a]
as = forall a. ([a] -> [a]) -> DList a
DList ([a]
as forall a. [a] -> [a] -> [a]
++)

toList :: DList a -> [a]
toList :: forall a. DList a -> [a]
toList = forall a. DList a -> [a]
runDList

snoc :: DList a -> a -> DList a
snoc :: forall a. DList a -> a -> DList a
snoc DList a
xs a
x = DList a
xs forall a. Semigroup a => a -> a -> a
<> forall a. a -> DList a
singleton a
x

instance Monoid (DList a) where
  mempty :: DList a
mempty  = forall a. DList a
empty
  mappend :: DList a -> DList a -> DList a
mappend = forall a. Semigroup a => a -> a -> a
(<>)

instance Semigroup (DList a) where
  DList [a] -> [a]
a <> :: DList a -> DList a -> DList a
<> DList [a] -> [a]
b = forall a. ([a] -> [a]) -> DList a
DList ([a] -> [a]
a forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
b)