    {-# LANGUAGE NoImplicitPrelude, MultiParamTypeClasses, FlexibleInstances #-}
    {-# OPTIONS -Wno-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