yaya-containers-0.1.2.0: src/Yaya/Containers/Pattern/IntMap.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE Safe #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Yaya.Containers.Pattern.IntMap
( IntMapF (BinF, NilF, TipF),
)
where
import "base" Control.Applicative (Alternative ((<|>)), Applicative ((<*>)), (*>))
import "base" Control.Category (Category ((.)))
import "base" Data.Bool (Bool (False, True), (&&))
import "base" Data.Eq (Eq ((==)))
import "base" Data.Foldable (Foldable)
import "base" Data.Function (($))
import "base" Data.Functor (Functor (fmap), (<$), (<$>))
import "base" Data.Ord (Ord (compare, (<=)), Ordering (EQ, GT, LT))
import "base" Data.Semigroup ((<>))
import "base" Data.Traversable (Traversable)
import qualified "base" Data.Tuple as Tuple
import "base" GHC.Generics (Generic, Generic1)
import "base" GHC.Read (Read (readListPrec, readPrec), expectP, parens)
import "base" Text.ParserCombinators.ReadPrec (prec, step)
import qualified "base" Text.Read.Lex as Lex
import qualified "containers" Data.IntMap.Internal as IntMap
import "yaya" Yaya.Fold
( Projectable (project),
Recursive (cata),
Steppable (embed),
)
import "base" Prelude (Num ((+)))
#if MIN_VERSION_base(4, 18, 0)
import "base" Data.Functor.Classes
( Eq1,
Eq2 (liftEq2),
Ord2 (liftCompare2),
Ord1,
Read1 (liftReadPrec),
Read2 (liftReadPrec2),
Show1,
Show2 (liftShowsPrec2),
)
import "base" Text.Show (Show (showsPrec), showParen, showString)
#else
import "base" Data.Functor.Classes
( Eq1 (liftEq),
Eq2 (liftEq2),
Ord1 (liftCompare),
Ord2 (liftCompare2),
Read1 (liftReadPrec),
Read2 (liftReadPrec2),
Show1 (liftShowsPrec),
Show2 (liftShowsPrec2),
)
import "base" Text.Show (Show (showList, showsPrec), showParen, showString)
#endif
data IntMapF a r
= NilF
| TipF IntMap.Key a
| BinF IntMap.Prefix IntMap.Mask r r
deriving stock
( Eq,
Ord,
Generic,
-- | @since 0.1.2.0
Read,
Show,
Foldable,
Functor,
Generic1,
Traversable
)
instance Projectable (->) (IntMap.IntMap a) (IntMapF a) where
project IntMap.Nil = NilF
project (IntMap.Tip key a) = TipF key a
project (IntMap.Bin prefix mask l r) = BinF prefix mask l r
instance Recursive (->) (IntMap.IntMap a) (IntMapF a) where
cata φ = φ . fmap (cata φ) . project
instance Steppable (->) (IntMap.IntMap a) (IntMapF a) where
embed NilF = IntMap.Nil
embed (TipF key a) = IntMap.Tip key a
embed (BinF prefix mask l r) = IntMap.Bin prefix mask l r
#if MIN_VERSION_base(4, 18, 0)
instance (Eq a) => Eq1 (IntMapF a)
#else
instance (Eq a) => Eq1 (IntMapF a) where
liftEq = liftEq2 (==)
#endif
instance Eq2 IntMapF where
liftEq2 f g = Tuple.curry $ \case
(NilF, NilF) -> True
(TipF key a, TipF key' a') -> key == key' && f a a'
(BinF prefix mask l r, BinF prefix' mask' l' r') ->
prefix == prefix' && mask == mask' && g l l' && g r r'
(_, _) -> False
#if MIN_VERSION_base(4, 18, 0)
instance (Ord a) => Ord1 (IntMapF a)
#else
instance (Ord a) => Ord1 (IntMapF a) where
liftCompare = liftCompare2 compare
#endif
instance Ord2 IntMapF where
liftCompare2 f g = Tuple.curry $ \case
(NilF, NilF) -> EQ
(NilF, _) -> LT
(TipF {}, NilF) -> GT
(TipF key a, TipF key' a') -> compare key key' <> f a a'
(TipF {}, BinF {}) -> LT
(BinF prefix mask l r, BinF prefix' mask' l' r') ->
compare prefix prefix' <> compare mask mask' <> g l l' <> g r r'
(BinF {}, _) -> GT
-- | @since 0.1.2.0
instance (Read a) => Read1 (IntMapF a) where
liftReadPrec = liftReadPrec2 readPrec readListPrec
-- | @since 0.1.2.0
instance Read2 IntMapF where
liftReadPrec2 readPrecA _ readPrecR _ =
let appPrec = 10
in parens . prec appPrec $
NilF
<$ expectP (Lex.Ident "NilF")
<|> expectP (Lex.Ident "TipF")
*> (TipF <$> step readPrec <*> step readPrecA)
<|> expectP (Lex.Ident "BinF")
*> ( BinF
<$> step readPrec
<*> step readPrec
<*> step readPrecR
<*> step readPrecR
)
#if MIN_VERSION_base(4, 18, 0)
instance (Show a) => Show1 (IntMapF a)
#else
instance (Show a) => Show1 (IntMapF a) where
liftShowsPrec = liftShowsPrec2 showsPrec showList
#endif
instance Show2 IntMapF where
liftShowsPrec2 showsPrecA _ showsPrecR _ p =
let appPrec = 10
nextPrec = appPrec + 1
in \case
NilF -> showString "NilF"
TipF key a ->
showParen (nextPrec <= p) $
showString "TipF "
. showsPrec nextPrec key
. showString " "
. showsPrecA nextPrec a
BinF prefix mask l r ->
showParen (nextPrec <= p) $
showString "BinF "
. showsPrec nextPrec prefix
. showString " "
. showsPrec nextPrec mask
. showString " "
. showsPrecR nextPrec l
. showString " "
. showsPrecR nextPrec r