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