{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Data.RAList.Internal (
RAList (..),
explicitShow,
explicitShowsPrec,
empty,
singleton,
cons,
(!),
(!?),
length,
null,
toList,
fromList,
ifoldMap,
adjust,
map,
imap,
itraverse,
) where
import Prelude
(Bool (..), Eq, Functor (..), Int, Maybe (..), Ord (..), Show (..),
ShowS, String, showParen, showString, ($), (.))
import Control.Applicative (Applicative (..), (<$>))
import Control.DeepSeq (NFData (..))
import Control.Exception (ArrayException (IndexOutOfBounds), throw)
import Data.Hashable (Hashable (..))
import Data.List.NonEmpty (NonEmpty (..))
import Data.Monoid (Monoid (..))
import Data.Semigroup (Semigroup (..))
import qualified Data.Foldable as I (Foldable (..))
import qualified Data.Traversable as I (Traversable (..))
import qualified Test.QuickCheck as QC
import qualified Data.RAList.NonEmpty.Internal as NE
data RAList a
= Empty
| NonEmpty (NE.NERAList a)
deriving (Eq, Ord, Functor, I.Traversable)
instance I.Foldable RAList where
foldMap _ Empty = mempty
foldMap f (NonEmpty xs) = I.foldMap f xs
#if MIN_VERSION_base(4,8,0)
length = length
null = null
#endif
instance NFData a => NFData (RAList a) where
rnf Empty = ()
rnf (NonEmpty xs) = rnf xs
instance Hashable a => Hashable (RAList a) where
hashWithSalt salt Empty = hashWithSalt salt (0 :: Int)
hashWithSalt salt (NonEmpty r) = hashWithSalt salt r
instance Semigroup (RAList a) where
Empty <> ys = ys
xs <> Empty = xs
NonEmpty xs <> NonEmpty ys = NonEmpty (xs <> ys)
instance Monoid (RAList a) where
mempty = Empty
mappend = (<>)
#ifdef MIN_VERSION_semigroupoids
#endif
instance Show a => Show (RAList a) where
showsPrec d xs = showParen (d > 10) $ showString "fromList " . showsPrec 11 (toList xs)
explicitShow :: Show a => RAList a -> String
explicitShow xs = explicitShowsPrec 0 xs ""
explicitShowsPrec :: Show a => Int -> RAList a -> ShowS
explicitShowsPrec _ Empty = showString "Empty"
explicitShowsPrec d (NonEmpty xs) = showParen (d > 10) $ showString "NonEmpty " . NE.explicitShowsPrec 11 xs
empty :: RAList a
empty = Empty
singleton :: a -> RAList a
singleton = NonEmpty . NE.singleton
cons :: a -> RAList a -> RAList a
cons x Empty = singleton x
cons x (NonEmpty xs) = NonEmpty (NE.cons x xs)
toList :: RAList a -> [a]
toList Empty = []
toList (NonEmpty xs) = I.foldr (:) [] xs
fromList :: [a] -> RAList a
fromList [] = Empty
fromList (x:xs) = NonEmpty (NE.fromNonEmpty (x :| xs))
(!) :: RAList a -> Int -> a
(!) Empty _ = throw $ IndexOutOfBounds "RAList"
(!) (NonEmpty xs) i = xs NE.! i
(!?) :: RAList a -> Int -> Maybe a
Empty !? _ = Nothing
NonEmpty xs !? i = xs NE.!? i
length :: RAList a -> Int
length Empty = 0
length (NonEmpty xs) = NE.length xs
null :: RAList a -> Bool
null Empty = True
null (NonEmpty _) = False
ifoldMap :: Monoid m => (Int -> a -> m) -> RAList a -> m
ifoldMap _ Empty = mempty
ifoldMap f (NonEmpty r) = NE.ifoldMap f r
map :: (a -> b) -> RAList a -> RAList b
map = fmap
imap :: (Int -> a -> b) -> RAList a -> RAList b
imap f xs = unI (itraverse (\i x -> I (f i x)) xs)
itraverse :: forall f a b. Applicative f => (Int -> a -> f b) -> RAList a -> f (RAList b)
itraverse _ Empty = pure Empty
itraverse f (NonEmpty xs) = NonEmpty <$> NE.itraverse f xs
adjust :: forall a. Int -> (a -> a) -> RAList a -> RAList a
adjust _ _ Empty = Empty
adjust i f (NonEmpty xs) = NonEmpty (NE.adjust i f xs)
instance QC.Arbitrary1 RAList where
liftArbitrary = fmap fromList . QC.liftArbitrary
liftShrink shr = fmap fromList . QC.liftShrink shr . toList
instance QC.Arbitrary a => QC.Arbitrary (RAList a) where
arbitrary = QC.arbitrary1
shrink = QC.shrink1
instance QC.CoArbitrary a => QC.CoArbitrary (RAList a) where
coarbitrary = QC.coarbitrary . toList
instance QC.Function a => QC.Function (RAList a) where
function = QC.functionMap toList fromList
newtype I a = I a
unI :: I a -> a
unI (I a) = a
instance Functor I where
fmap f (I x) = I (f x)
instance Applicative I where
pure = I
I f <*> I x = I (f x)
_ *> x = x
x <* _ = x
#if MIN_VERSION_base(4,10,0)
liftA2 f (I x) (I y) = I (f x y)
#endif