{-# LANGUAGE CPP #-}
module Acc
(
Acc,
cons,
snoc,
uncons,
unsnoc,
toNonEmpty,
toNeAcc,
enumFromTo,
)
where
import Acc.Prelude hiding (toNonEmpty, enumFromTo)
import qualified Acc.NeAcc as NeAcc
import qualified Acc.NeAcc.Def as NeAcc
import qualified Data.Foldable as Foldable
import qualified Data.Semigroup.Foldable as Foldable1
data Acc a =
EmptyAcc |
TreeAcc !(NeAcc.NeAcc a)
deriving (Generic, Generic1)
instance NFData a => NFData (Acc a)
instance NFData1 Acc
deriving instance Functor Acc
instance Foldable Acc where
foldMap f =
\ case
TreeAcc a ->
foldMap f a
EmptyAcc ->
mempty
#if MIN_VERSION_base(4,13,0)
foldMap' f =
\ case
TreeAcc a ->
foldMap' f a
EmptyAcc ->
mempty
#endif
foldr step acc =
\ case
TreeAcc a ->
foldr step acc a
EmptyAcc ->
acc
foldr' step acc =
\ case
TreeAcc a ->
foldr' step acc a
EmptyAcc ->
acc
foldl step acc =
\ case
TreeAcc a ->
foldl step acc a
EmptyAcc ->
acc
foldl' step acc =
\ case
TreeAcc a ->
foldl' step acc a
EmptyAcc ->
acc
sum =
foldl' (+) 0
instance Traversable Acc where
traverse f =
\ case
TreeAcc a ->
TreeAcc <$> traverse f a
EmptyAcc ->
pure EmptyAcc
instance Applicative Acc where
pure =
TreeAcc . NeAcc.Leaf
(<*>) =
\ case
TreeAcc a ->
\ case
TreeAcc b ->
TreeAcc (a <*> b)
EmptyAcc ->
EmptyAcc
EmptyAcc ->
const EmptyAcc
instance Alternative Acc where
empty =
EmptyAcc
(<|>) =
\ case
TreeAcc a ->
\ case
TreeAcc b ->
TreeAcc (NeAcc.Branch a b)
EmptyAcc ->
TreeAcc a
EmptyAcc ->
id
instance Semigroup (Acc a) where
(<>) =
(<|>)
instance Monoid (Acc a) where
mempty =
empty
mappend =
(<>)
instance IsList (Acc a) where
type Item (Acc a) = a
fromList =
\ case
a : b -> TreeAcc (NeAcc.fromList1 a b)
_ -> EmptyAcc
toList =
\ case
TreeAcc a ->
foldr (:) [] a
_ ->
[]
instance Show a => Show (Acc a) where
show =
show . toList
cons :: a -> Acc a -> Acc a
cons a =
\ case
TreeAcc tree ->
TreeAcc (NeAcc.Branch (NeAcc.Leaf a) tree)
EmptyAcc ->
TreeAcc (NeAcc.Leaf a)
uncons :: Acc a -> Maybe (a, Acc a)
uncons =
\ case
TreeAcc tree ->
case tree of
NeAcc.Branch l r ->
case NeAcc.unconsTo r l of
(res, newTree) ->
Just (res, TreeAcc newTree)
NeAcc.Leaf res ->
Just (res, EmptyAcc)
EmptyAcc ->
Nothing
snoc :: a -> Acc a -> Acc a
snoc a =
\ case
TreeAcc tree ->
TreeAcc (NeAcc.Branch tree (NeAcc.Leaf a))
EmptyAcc ->
TreeAcc (NeAcc.Leaf a)
unsnoc :: Acc a -> Maybe (a, Acc a)
unsnoc =
\ case
TreeAcc tree ->
case tree of
NeAcc.Branch l r ->
case NeAcc.unsnocTo l r of
(res, newTree) ->
Just (res, TreeAcc newTree)
NeAcc.Leaf res ->
Just (res, EmptyAcc)
EmptyAcc ->
Nothing
toNonEmpty :: Acc a -> Maybe (NonEmpty a)
toNonEmpty =
fmap Foldable1.toNonEmpty . toNeAcc
toNeAcc :: Acc a -> Maybe (NeAcc.NeAcc a)
toNeAcc =
\ case
TreeAcc tree ->
Just tree
EmptyAcc ->
Nothing
enumFromTo :: (Enum a, Ord a) => a -> a -> Acc a
enumFromTo from to =
if from <= to
then
TreeAcc (NeAcc.appendEnumFromTo (succ from) to (NeAcc.Leaf from))
else
EmptyAcc