-- | -- Module : Foundation.List.DList -- License : BSD-style -- Maintainer : Nicolas Di Prima -- Stability : statble -- Portability : portable -- -- Data structure for optimised operations (append, cons, snoc) on list -- module Foundation.List.DList ( DList ) where import Basement.Compat.Base import Basement.Compat.Semigroup import Basement.Compat.Bifunctor import Foundation.Collection newtype DList a = DList { unDList :: [a] -> [a] } deriving (Typeable) instance Eq a => Eq (DList a) where (==) dl1 dl2 = (==) (toList dl1) (toList dl2) instance Ord a => Ord (DList a) where compare dl1 dl2 = compare (toList dl1) (toList dl2) instance Show a => Show (DList a) where show = show . toList instance IsList (DList a) where type Item (DList a) = a fromList = DList . (Basement.Compat.Semigroup.<>) toList = flip unDList [] instance Semigroup (DList a) where (<>) dl1 dl2 = DList $ unDList dl1 . unDList dl2 instance Monoid (DList a) where mempty = DList id mappend dl1 dl2 = DList $ unDList dl1 . unDList dl2 instance Functor DList where fmap f = foldr (cons . f) mempty instance Applicative DList where pure = singleton (<*>) m1 m2 = m1 >>= \x1 -> m2 >>= \x2 -> return (x1 x2) instance Monad DList where (>>=) m k = foldr (mappend . k) mempty m return = singleton type instance Element (DList a) = a instance Foldable (DList a) where foldr f b = foldr f b . toList foldl' f b = foldl' f b . toList instance Collection (DList a) where null = null . toList length = length . toList elem a = elem a . toList maximum = maximum . nonEmpty_ . toList minimum = minimum . nonEmpty_ . toList all f = all f . toList any f = any f . toList instance Sequential (DList a) where take n = fromList . take n . toList revTake n = fromList . revTake n . toList drop n = fromList . drop n . toList revDrop n = fromList . revDrop n . toList splitAt n = bimap fromList fromList . splitAt n . toList splitOn f = fmap fromList . splitOn f . toList break f = bimap fromList fromList . break f . toList breakEnd f = bimap fromList fromList . breakEnd f . toList breakElem e = bimap fromList fromList . breakElem e . toList intersperse e = fromList . intersperse e . toList intercalate e = intercalate e . toList span f = bimap fromList fromList . span f . toList spanEnd f = bimap fromList fromList . spanEnd f . toList filter f = fromList . filter f . toList partition f = bimap fromList fromList . partition f . toList reverse = fromList . reverse . toList uncons dl = second fromList <$> uncons (toList dl) unsnoc dl = first fromList <$> unsnoc (toList dl) cons e dl = DList $ (:) e . unDList dl snoc dl e = DList $ unDList dl . (:) e find f = find f . toList sortBy comp = fromList . sortBy comp . toList singleton = DList . (:) replicate n e = fromList $ replicate n e