{-# OPTIONS_GHC -O2 #-}
{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE CPP #-}
#if !defined(__GLASGOW_HASKELL__)
#error "Your compiler is not GHC. Let us know if dlist can be made to work on it."
#endif
{-# LANGUAGE TypeFamilies #-}
#if __GLASGOW_HASKELL__ >= 708
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE Unsafe #-}
{-# LANGUAGE ViewPatterns #-}
#endif
module Data.DList.Internal where
import qualified Control.Applicative as Applicative
import Control.DeepSeq (NFData (..))
import qualified Control.Monad as Monad
#if MIN_VERSION_base(4,9,0) && !MIN_VERSION_base(4,13,0)
import qualified Control.Monad.Fail as Monad
#endif
import qualified Data.Foldable as Foldable
import Data.Function (on)
import qualified Data.List as List
import qualified Data.Monoid as Monoid
#if MIN_VERSION_base(4,9,0)
import qualified Data.Semigroup as Semigroup
#endif
import Data.String (IsString (..))
import qualified Data.Traversable as Traversable
#if __GLASGOW_HASKELL__ >= 708
import qualified GHC.Exts as Exts
#endif
import qualified Text.Read as Read
import Prelude hiding (concat, foldr, head, map, replicate, tail)
newtype DList a = UnsafeDList {DList a -> [a] -> [a]
unsafeApplyDList :: [a] -> [a]}
{-# INLINE fromList #-}
fromList :: [a] -> DList a
fromList :: [a] -> DList a
fromList = ([a] -> [a]) -> DList a
forall a. ([a] -> [a]) -> DList a
UnsafeDList (([a] -> [a]) -> DList a) -> ([a] -> [a] -> [a]) -> [a] -> DList a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++)
{-# INLINE toList #-}
toList :: DList a -> [a]
toList :: DList a -> [a]
toList = (([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ []) (([a] -> [a]) -> [a]) -> (DList a -> [a] -> [a]) -> DList a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a] -> [a]
forall a. DList a -> [a] -> [a]
unsafeApplyDList
#if __GLASGOW_HASKELL__ >= 708
#if __GLASGOW_HASKELL__ >= 710
pattern Nil :: DList a
#endif
pattern $mNil :: forall r a. DList a -> (Void# -> r) -> (Void# -> r) -> r
Nil <- (toList -> [])
#if __GLASGOW_HASKELL__ >= 710
pattern Cons :: a -> [a] -> DList a
#endif
pattern $mCons :: forall r a. DList a -> (a -> [a] -> r) -> (Void# -> r) -> r
Cons x xs <- (toList -> x : xs)
#endif
{-# INLINE apply #-}
apply :: DList a -> [a] -> [a]
apply :: DList a -> [a] -> [a]
apply = DList a -> [a] -> [a]
forall a. DList a -> [a] -> [a]
unsafeApplyDList
{-# INLINE empty #-}
empty :: DList a
empty :: DList a
empty = ([a] -> [a]) -> DList a
forall a. ([a] -> [a]) -> DList a
UnsafeDList [a] -> [a]
forall a. a -> a
id
{-# INLINE singleton #-}
singleton :: a -> DList a
singleton :: a -> DList a
singleton = ([a] -> [a]) -> DList a
forall a. ([a] -> [a]) -> DList a
UnsafeDList (([a] -> [a]) -> DList a) -> (a -> [a] -> [a]) -> a -> DList a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:)
infixr 9 `cons`
{-# INLINE cons #-}
cons :: a -> DList a -> DList a
cons :: a -> DList a -> DList a
cons a
x DList a
xs = ([a] -> [a]) -> DList a
forall a. ([a] -> [a]) -> DList a
UnsafeDList (([a] -> [a]) -> DList a) -> ([a] -> [a]) -> DList a
forall a b. (a -> b) -> a -> b
$ (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a] -> [a]
forall a. DList a -> [a] -> [a]
unsafeApplyDList DList a
xs
infixl 9 `snoc`
{-# INLINE snoc #-}
snoc :: DList a -> a -> DList a
snoc :: DList a -> a -> DList a
snoc DList a
xs a
x = ([a] -> [a]) -> DList a
forall a. ([a] -> [a]) -> DList a
UnsafeDList (([a] -> [a]) -> DList a) -> ([a] -> [a]) -> DList a
forall a b. (a -> b) -> a -> b
$ DList a -> [a] -> [a]
forall a. DList a -> [a] -> [a]
unsafeApplyDList DList a
xs ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:)
{-# INLINE append #-}
append :: DList a -> DList a -> DList a
append :: DList a -> DList a -> DList a
append DList a
xs DList a
ys = ([a] -> [a]) -> DList a
forall a. ([a] -> [a]) -> DList a
UnsafeDList (([a] -> [a]) -> DList a) -> ([a] -> [a]) -> DList a
forall a b. (a -> b) -> a -> b
$ DList a -> [a] -> [a]
forall a. DList a -> [a] -> [a]
unsafeApplyDList DList a
xs ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a] -> [a]
forall a. DList a -> [a] -> [a]
unsafeApplyDList DList a
ys
{-# INLINE concat #-}
concat :: [DList a] -> DList a
concat :: [DList a] -> DList a
concat = (DList a -> DList a -> DList a) -> DList a -> [DList a] -> DList a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr DList a -> DList a -> DList a
forall a. DList a -> DList a -> DList a
append DList a
forall a. DList a
empty
{-# INLINE replicate #-}
replicate :: Int -> a -> DList a
replicate :: Int -> a -> DList a
replicate Int
n a
x = ([a] -> [a]) -> DList a
forall a. ([a] -> [a]) -> DList a
UnsafeDList (([a] -> [a]) -> DList a) -> ([a] -> [a]) -> DList a
forall a b. (a -> b) -> a -> b
$ \[a]
xs ->
let go :: Int -> [a]
go Int
m
| Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = [a]
xs
| Bool
otherwise = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Int -> [a]
go (Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
in Int -> [a]
go Int
n
{-# INLINE head #-}
head :: DList a -> a
head :: DList a -> a
head DList a
xs = case DList a -> [a]
forall a. DList a -> [a]
toList DList a
xs of
a
x : [a]
_ -> a
x
[] -> [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"Data.DList.head: empty DList"
{-# INLINE tail #-}
tail :: DList a -> [a]
tail :: DList a -> [a]
tail DList a
xs = case DList a -> [a]
forall a. DList a -> [a]
toList DList a
xs of
a
_ : [a]
ys -> [a]
ys
[] -> [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"Data.DList.tail: empty DList"
unfoldr :: (b -> Maybe (a, b)) -> b -> DList a
unfoldr :: (b -> Maybe (a, b)) -> b -> DList a
unfoldr b -> Maybe (a, b)
f b
z =
case b -> Maybe (a, b)
f b
z of
Maybe (a, b)
Nothing -> DList a
forall a. DList a
empty
Just (a
x, b
z') -> a -> DList a -> DList a
forall a. a -> DList a -> DList a
cons a
x (DList a -> DList a) -> DList a -> DList a
forall a b. (a -> b) -> a -> b
$ (b -> Maybe (a, b)) -> b -> DList a
forall b a. (b -> Maybe (a, b)) -> b -> DList a
unfoldr b -> Maybe (a, b)
f b
z'
{-# INLINE foldr #-}
foldr :: (a -> b -> b) -> b -> DList a -> b
foldr :: (a -> b -> b) -> b -> DList a -> b
foldr a -> b -> b
f b
z = (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr a -> b -> b
f b
z ([a] -> b) -> (DList a -> [a]) -> DList a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a]
forall a. DList a -> [a]
toList
{-# INLINE map #-}
map :: (a -> b) -> DList a -> DList b
map :: (a -> b) -> DList a -> DList b
map a -> b
f = (a -> DList b -> DList b) -> DList b -> DList a -> DList b
forall a b. (a -> b -> b) -> b -> DList a -> b
foldr (b -> DList b -> DList b
forall a. a -> DList a -> DList a
cons (b -> DList b -> DList b) -> (a -> b) -> a -> DList b -> DList b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) DList b
forall a. DList a
empty
{-# INLINE intercalate #-}
intercalate :: DList a -> [DList a] -> DList a
intercalate :: DList a -> [DList a] -> DList a
intercalate DList a
sep = [DList a] -> DList a
forall a. [DList a] -> DList a
concat ([DList a] -> DList a)
-> ([DList a] -> [DList a]) -> [DList a] -> DList a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [DList a] -> [DList a]
forall a. a -> [a] -> [a]
List.intersperse DList a
sep
instance Eq a => Eq (DList a) where
== :: DList a -> DList a -> Bool
(==) = [a] -> [a] -> Bool
forall a. Eq a => a -> a -> Bool
(==) ([a] -> [a] -> Bool)
-> (DList a -> [a]) -> DList a -> DList a -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` DList a -> [a]
forall a. DList a -> [a]
toList
instance Ord a => Ord (DList a) where
compare :: DList a -> DList a -> Ordering
compare = [a] -> [a] -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ([a] -> [a] -> Ordering)
-> (DList a -> [a]) -> DList a -> DList a -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` DList a -> [a]
forall a. DList a -> [a]
toList
instance Read a => Read (DList a) where
readPrec :: ReadPrec (DList a)
readPrec = ReadPrec (DList a) -> ReadPrec (DList a)
forall a. ReadPrec a -> ReadPrec a
Read.parens (ReadPrec (DList a) -> ReadPrec (DList a))
-> ReadPrec (DList a) -> ReadPrec (DList a)
forall a b. (a -> b) -> a -> b
$
Int -> ReadPrec (DList a) -> ReadPrec (DList a)
forall a. Int -> ReadPrec a -> ReadPrec a
Read.prec Int
10 (ReadPrec (DList a) -> ReadPrec (DList a))
-> ReadPrec (DList a) -> ReadPrec (DList a)
forall a b. (a -> b) -> a -> b
$ do
Read.Ident [Char]
"fromList" <- ReadPrec Lexeme
Read.lexP
[a]
dl <- ReadPrec [a]
forall a. Read a => ReadPrec a
Read.readPrec
DList a -> ReadPrec (DList a)
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> DList a
forall a. [a] -> DList a
fromList [a]
dl)
readListPrec :: ReadPrec [DList a]
readListPrec = ReadPrec [DList a]
forall a. Read a => ReadPrec [a]
Read.readListPrecDefault
instance Show a => Show (DList a) where
showsPrec :: Int -> DList a -> ShowS
showsPrec Int
p DList a
dl =
Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
[Char] -> ShowS
showString [Char]
"fromList " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> ShowS
forall a. Show a => a -> ShowS
shows (DList a -> [a]
forall a. DList a -> [a]
toList DList a
dl)
instance Monoid.Monoid (DList a) where
{-# INLINE mempty #-}
mempty :: DList a
mempty = DList a
forall a. DList a
empty
#if MIN_VERSION_base(4,11,0)
#else
{-# INLINE mappend #-}
#if MIN_VERSION_base(4,9,0)
mappend = (Semigroup.<>)
#else
mappend = append
#endif
#endif
instance Functor DList where
{-# INLINE fmap #-}
fmap :: (a -> b) -> DList a -> DList b
fmap = (a -> b) -> DList a -> DList b
forall a b. (a -> b) -> DList a -> DList b
map
instance Applicative.Applicative DList where
{-# INLINE pure #-}
pure :: a -> DList a
pure = a -> DList a
forall a. a -> DList a
singleton
{-# INLINE (<*>) #-}
<*> :: DList (a -> b) -> DList a -> DList b
(<*>) = DList (a -> b) -> DList a -> DList b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
Monad.ap
instance Applicative.Alternative DList where
{-# INLINE empty #-}
empty :: DList a
empty = DList a
forall a. DList a
empty
{-# INLINE (<|>) #-}
<|> :: DList a -> DList a -> DList a
(<|>) = DList a -> DList a -> DList a
forall a. DList a -> DList a -> DList a
append
instance Monad DList where
{-# INLINE (>>=) #-}
DList a
m >>= :: DList a -> (a -> DList b) -> DList b
>>= a -> DList b
k =
(a -> DList b -> DList b) -> DList b -> DList a -> DList b
forall a b. (a -> b -> b) -> b -> DList a -> b
foldr (DList b -> DList b -> DList b
forall a. DList a -> DList a -> DList a
append (DList b -> DList b -> DList b)
-> (a -> DList b) -> a -> DList b -> DList b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> DList b
k) DList b
forall a. DList a
empty DList a
m
{-# INLINE return #-}
return :: a -> DList a
return = a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
Applicative.pure
#if !MIN_VERSION_base(4,13,0)
{-# INLINE fail #-}
fail _ = empty
#endif
#if MIN_VERSION_base(4,9,0)
instance Monad.MonadFail DList where
{-# INLINE fail #-}
fail :: [Char] -> DList a
fail [Char]
_ = DList a
forall a. DList a
empty
#endif
instance Monad.MonadPlus DList where
{-# INLINE mzero #-}
mzero :: DList a
mzero = DList a
forall a. DList a
empty
{-# INLINE mplus #-}
mplus :: DList a -> DList a -> DList a
mplus = DList a -> DList a -> DList a
forall a. DList a -> DList a -> DList a
append
instance Foldable.Foldable DList where
{-# INLINE fold #-}
fold :: DList m -> m
fold = [m] -> m
forall a. Monoid a => [a] -> a
Monoid.mconcat ([m] -> m) -> (DList m -> [m]) -> DList m -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList m -> [m]
forall a. DList a -> [a]
toList
{-# INLINE foldMap #-}
foldMap :: (a -> m) -> DList a -> m
foldMap a -> m
f = (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
Foldable.foldMap a -> m
f ([a] -> m) -> (DList a -> [a]) -> DList a -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a]
forall a. DList a -> [a]
toList
{-# INLINE foldr #-}
foldr :: (a -> b -> b) -> b -> DList a -> b
foldr a -> b -> b
f b
x = (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr a -> b -> b
f b
x ([a] -> b) -> (DList a -> [a]) -> DList a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a]
forall a. DList a -> [a]
toList
{-# INLINE foldl #-}
foldl :: (b -> a -> b) -> b -> DList a -> b
foldl b -> a -> b
f b
x = (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl b -> a -> b
f b
x ([a] -> b) -> (DList a -> [a]) -> DList a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a]
forall a. DList a -> [a]
toList
{-# INLINE foldr1 #-}
foldr1 :: (a -> a -> a) -> DList a -> a
foldr1 a -> a -> a
f = (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
List.foldr1 a -> a -> a
f ([a] -> a) -> (DList a -> [a]) -> DList a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a]
forall a. DList a -> [a]
toList
{-# INLINE foldl1 #-}
foldl1 :: (a -> a -> a) -> DList a -> a
foldl1 a -> a -> a
f = (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
List.foldl1 a -> a -> a
f ([a] -> a) -> (DList a -> [a]) -> DList a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a]
forall a. DList a -> [a]
toList
#if __GLASGOW_HASKELL__ >= 706
{-# INLINE foldl' #-}
foldl' :: (b -> a -> b) -> b -> DList a -> b
foldl' b -> a -> b
f b
x = (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' b -> a -> b
f b
x ([a] -> b) -> (DList a -> [a]) -> DList a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a]
forall a. DList a -> [a]
toList
{-# INLINE foldr' #-}
foldr' :: (a -> b -> b) -> b -> DList a -> b
foldr' a -> b -> b
f b
x = (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
Foldable.foldr' a -> b -> b
f b
x ([a] -> b) -> (DList a -> [a]) -> DList a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a]
forall a. DList a -> [a]
toList
#endif
#if MIN_VERSION_base(4,8,0)
{-# INLINE toList #-}
toList :: DList a -> [a]
toList = DList a -> [a]
forall a. DList a -> [a]
Data.DList.Internal.toList
#endif
instance Traversable.Traversable DList where
{-# INLINE traverse #-}
traverse :: (a -> f b) -> DList a -> f (DList b)
traverse a -> f b
f = (a -> f (DList b) -> f (DList b))
-> f (DList b) -> DList a -> f (DList b)
forall a b. (a -> b -> b) -> b -> DList a -> b
foldr a -> f (DList b) -> f (DList b)
cons_f (DList b -> f (DList b)
forall (f :: * -> *) a. Applicative f => a -> f a
Applicative.pure DList b
forall a. DList a
empty)
where
cons_f :: a -> f (DList b) -> f (DList b)
cons_f a
x = (b -> DList b -> DList b) -> f b -> f (DList b) -> f (DList b)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
Applicative.liftA2 b -> DList b -> DList b
forall a. a -> DList a -> DList a
cons (a -> f b
f a
x)
instance NFData a => NFData (DList a) where
{-# INLINE rnf #-}
rnf :: DList a -> ()
rnf = [a] -> ()
forall a. NFData a => a -> ()
rnf ([a] -> ()) -> (DList a -> [a]) -> DList a -> ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DList a -> [a]
forall a. DList a -> [a]
toList
instance a ~ Char => IsString (DList a) where
{-# INLINE fromString #-}
fromString :: [Char] -> DList a
fromString = [Char] -> DList a
forall a. [a] -> DList a
fromList
#if __GLASGOW_HASKELL__ >= 708
instance Exts.IsList (DList a) where
type Item (DList a) = a
{-# INLINE fromList #-}
fromList :: [Item (DList a)] -> DList a
fromList = [Item (DList a)] -> DList a
forall a. [a] -> DList a
fromList
{-# INLINE toList #-}
toList :: DList a -> [Item (DList a)]
toList = DList a -> [Item (DList a)]
forall a. DList a -> [a]
toList
#endif
#if MIN_VERSION_base(4,9,0)
instance Semigroup.Semigroup (DList a) where
{-# INLINE (<>) #-}
<> :: DList a -> DList a -> DList a
(<>) = DList a -> DList a -> DList a
forall a. DList a -> DList a -> DList a
append
stimes :: b -> DList a -> DList a
stimes b
n = case b -> b -> Ordering
forall a. Ord a => a -> a -> Ordering
compare b
n b
0 of
Ordering
LT -> [Char] -> DList a -> DList a
forall a. HasCallStack => [Char] -> a
error [Char]
"Data.DList.stimes: negative multiplier"
Ordering
_ -> b -> DList a -> DList a
forall b a. (Integral b, Monoid a) => b -> a -> a
Semigroup.stimesMonoid b
n
#endif