{-# LANGUAGE NoImplicitPrelude, MultiParamTypeClasses, FlexibleInstances #-}
{-# OPTIONS -fno-warn-orphans #-}
{-# LANGUAGE CPP #-}

-- | 'Data.ListLike.ListLike' instances for 'Data.DList.DList'

module Data.ListLike.DList () where

import qualified Prelude

import Data.ListLike.Base
import Data.ListLike.FoldableLL
import Data.ListLike.String
#if MIN_VERSION_dlist(1,0,0)
import Data.DList.Unsafe (DList(UnsafeDList), unsafeApplyDList)
#else
import Data.DList (DList)
#endif
import qualified Data.DList as D
import qualified Data.Foldable as F
import qualified Data.List as List
import qualified Data.String as S
import Control.Category
import Data.Char (Char)


instance FoldableLL (DList a) a where
  foldl :: forall a. (a -> a -> a) -> a -> DList a -> a
foldl = (a -> a -> a) -> a -> DList a -> a
forall b a. (b -> a -> b) -> b -> DList a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl
  foldr :: forall b. (a -> b -> b) -> b -> DList a -> b
foldr = (a -> b -> b) -> b -> DList a -> b
forall a b. (a -> b -> b) -> b -> DList a -> b
D.foldr
  foldl1 :: (a -> a -> a) -> DList a -> a
foldl1 = (a -> a -> a) -> DList a -> a
forall a. (a -> a -> a) -> DList a -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
F.foldl1
  foldr1 :: (a -> a -> a) -> DList a -> a
foldr1 = (a -> a -> a) -> DList a -> a
forall a. (a -> a -> a) -> DList a -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
F.foldr1
  foldl' :: forall a. (a -> a -> a) -> a -> DList a -> a
foldl' = (a -> a -> a) -> a -> DList a -> a
forall b a. (b -> a -> b) -> b -> DList a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl'
  foldr' :: forall b. (a -> b -> b) -> b -> DList a -> b
foldr' = (a -> b -> b) -> b -> DList a -> b
forall a b. (a -> b -> b) -> b -> DList a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr'

instance ListLike (DList a) a where
  empty :: DList a
empty = DList a
forall a. DList a
D.empty
  singleton :: a -> DList a
singleton = a -> DList a
forall a. a -> DList a
D.singleton
  cons :: a -> DList a -> DList a
cons = a -> DList a -> DList a
forall a. a -> DList a -> DList a
D.cons
  snoc :: DList a -> a -> DList a
snoc = DList a -> a -> DList a
forall a. DList a -> a -> DList a
D.snoc
  append :: DList a -> DList a -> DList a
append = DList a -> DList a -> DList a
forall a. DList a -> DList a -> DList a
D.append
  head :: DList a -> a
head = DList a -> a
forall a. DList a -> a
D.head
#if MIN_VERSION_dlist(1,0,0)
  -- Andreas Abel, 2021-09-01, issue #14,
  -- work around https://github.com/spl/dlist/issues/98:
  --
  -- dlist-1.0 changed @tail@ so that it is not an operation
  -- on difference lists anymore, but collapses the difference list
  -- into a plain list.
  --
  -- The following tail function restores the spirit of difference
  -- lists, at the cost of breaking data abstraction, i.e.,
  -- using the constructor and destructor of the newtype DList.
  -- Andreas Abel, 2023-10-10, issue #32:
  -- Use @drop 1@ instead of @tail@ as the latter triggers the x-partial warning in GHC 9.8.
  tail :: DList a -> DList a
tail = ([a] -> [a]) -> DList a
forall a. ([a] -> [a]) -> DList a
UnsafeDList (([a] -> [a]) -> DList a)
-> (DList a -> [a] -> [a]) -> DList a -> DList a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
List.drop Int
1 ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
.) (([a] -> [a]) -> [a] -> [a])
-> (DList a -> [a] -> [a]) -> DList a -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. DList a -> [a] -> [a]
forall a. DList a -> [a] -> [a]
unsafeApplyDList
#else
  tail = D.tail
#endif
  rigidMap :: (a -> a) -> DList a -> DList a
rigidMap = (a -> a) -> DList a -> DList a
forall a b. (a -> b) -> DList a -> DList b
D.map
  null :: DList a -> Bool
null = [a] -> Bool
forall full item. ListLike full item => full -> Bool
null ([a] -> Bool) -> (DList a -> [a]) -> DList a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. DList a -> [a]
forall a. DList a -> [a]
D.toList
  --toList = D.toList
  --fromList = D.fromList
  replicate :: Int -> a -> DList a
replicate = Int -> a -> DList a
forall a. Int -> a -> DList a
D.replicate
  uncons :: DList a -> Maybe (a, DList a)
uncons DList a
xs = case DList a
xs of
    DList a
D.Nil -> Maybe (a, DList a)
forall a. Maybe a
Prelude.Nothing
    D.Cons a
d_head [a]
l_tail -> (a, DList a) -> Maybe (a, DList a)
forall a. a -> Maybe a
Prelude.Just (a
d_head,[Item (DList a)] -> DList a
forall l. IsList l => [Item l] -> l
fromList [a]
[Item (DList a)]
l_tail)
    DList a
_ -> [Char] -> Maybe (a, DList a)
forall a. HasCallStack => [Char] -> a
Prelude.error [Char]
"Workaround for missing COMPLETE pragma on dlist patterns"


instance StringLike (DList Char) where
  toString :: DList Char -> [Char]
toString = DList Char -> [Char]
forall a. DList a -> [a]
D.toList
  -- fromString = D.fromList
  lines :: forall full. ListLike full (DList Char) => DList Char -> full
lines = ([Char] -> DList Char) -> [[Char]] -> full
forall full' item'.
ListLike full' item' =>
([Char] -> item') -> [[Char]] -> full'
forall full item full' item'.
(ListLike full item, ListLike full' item') =>
(item -> item') -> full -> full'
map [Char] -> DList Char
forall a. [a] -> DList a
D.fromList ([[Char]] -> full)
-> (DList Char -> [[Char]]) -> DList Char -> full
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [Char] -> [[Char]]
S.lines ([Char] -> [[Char]])
-> (DList Char -> [Char]) -> DList Char -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. DList Char -> [Char]
forall a. DList a -> [a]
D.toList
  words :: forall full. ListLike full (DList Char) => DList Char -> full
words = ([Char] -> DList Char) -> [[Char]] -> full
forall full' item'.
ListLike full' item' =>
([Char] -> item') -> [[Char]] -> full'
forall full item full' item'.
(ListLike full item, ListLike full' item') =>
(item -> item') -> full -> full'
map [Char] -> DList Char
forall a. [a] -> DList a
D.fromList ([[Char]] -> full)
-> (DList Char -> [[Char]]) -> DList Char -> full
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [Char] -> [[Char]]
S.words ([Char] -> [[Char]])
-> (DList Char -> [Char]) -> DList Char -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. DList Char -> [Char]
forall a. DList a -> [a]
D.toList
  unlines :: forall full. ListLike full (DList Char) => full -> DList Char
unlines = [Char] -> DList Char
forall a. [a] -> DList a
D.fromList ([Char] -> DList Char) -> (full -> [Char]) -> full -> DList Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [[Char]] -> [Char]
S.unlines ([[Char]] -> [Char]) -> (full -> [[Char]]) -> full -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (DList Char -> [Char]) -> full -> [[Char]]
forall full' item'.
ListLike full' item' =>
(DList Char -> item') -> full -> full'
forall full item full' item'.
(ListLike full item, ListLike full' item') =>
(item -> item') -> full -> full'
map DList Char -> [Char]
forall a. DList a -> [a]
D.toList
  unwords :: forall full. ListLike full (DList Char) => full -> DList Char
unwords = [Char] -> DList Char
forall a. [a] -> DList a
D.fromList ([Char] -> DList Char) -> (full -> [Char]) -> full -> DList Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [[Char]] -> [Char]
S.unwords ([[Char]] -> [Char]) -> (full -> [[Char]]) -> full -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (DList Char -> [Char]) -> full -> [[Char]]
forall full' item'.
ListLike full' item' =>
(DList Char -> item') -> full -> full'
forall full item full' item'.
(ListLike full item, ListLike full' item') =>
(item -> item') -> full -> full'
map DList Char -> [Char]
forall a. DList a -> [a]
D.toList