{-# LANGUAGE MultiWayIf       #-}
{-# LANGUAGE ViewPatterns     #-}
{-# LANGUAGE Strict           #-}
{-# LANGUAGE DeriveGeneric    #-}
{-# LANGUAGE TypeApplications #-}


-- |
-- Module      :  Data.RLE.Internal
-- Copyright   :  (c) Matthew Mosior 2022
-- License     :  BSD-style
-- Maintainer  :  mattm.github@gmail.com
-- Portability :  portable
--
-- = WARNING
--
-- This module is considered __internal__.
--
-- The Package Versioning Policy __does not apply__.
--
-- The contents of this module may change __in any way whatsoever__
-- and __without any warning__ between minor versions of this package.
--
-- Authors importing this library are expected to track development
-- closely.
--
-- All credit goes to the author(s)/maintainer(s) of the
-- [containers](https://hackage.haskell.org/package/containers) library
-- for the above warning text.
--
-- = Description
--
-- Various data structures and custom data types to describe the Run-length encoding (RLE)
-- and the Inverse RLE implementations, namely 'seqToRLEB', 'seqToRLET', 'seqFromRLEB', and 'seqFromRLET'.
--
-- The RLE implementations rely heavily upon 'Seq' provided by the [containers](https://hackage.haskell.org/package/containers),
-- 'STRef' and associated functions in the [stref](https://hackage.haskell.org/package/base-4.17.0.0/docs/Data-STRef.html) library,
-- and 'runST' in the [Control.Monad.ST](https://hackage.haskell.org/package/base-4.17.0.0/docs/Control-Monad-ST.html) library.


module Data.RLE.Internal where

import Control.Monad as CM
import Control.Monad.ST as CMST
import Control.Monad.State.Strict()
import Data.ByteString as BS
import Data.ByteString.Char8 as BSC8 (pack,unpack)
import Data.ByteString.Internal()
import Data.List()
import Data.Maybe as DMaybe (fromJust,isJust,isNothing)
import Data.Sequence as DS (Seq(..),empty,(|>))
import Data.Sequence.Internal as DSI
import Data.STRef as DSTR
import Data.Text as DText
import GHC.Generics (Generic)
import Prelude as P


{-Base level types.-}

-- | Basic RLE ('ByteString') data type.
newtype RLEB = RLEB (Seq (Maybe ByteString))
  deriving (RLEB -> RLEB -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RLEB -> RLEB -> Bool
$c/= :: RLEB -> RLEB -> Bool
== :: RLEB -> RLEB -> Bool
$c== :: RLEB -> RLEB -> Bool
Eq,Eq RLEB
RLEB -> RLEB -> Bool
RLEB -> RLEB -> Ordering
RLEB -> RLEB -> RLEB
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RLEB -> RLEB -> RLEB
$cmin :: RLEB -> RLEB -> RLEB
max :: RLEB -> RLEB -> RLEB
$cmax :: RLEB -> RLEB -> RLEB
>= :: RLEB -> RLEB -> Bool
$c>= :: RLEB -> RLEB -> Bool
> :: RLEB -> RLEB -> Bool
$c> :: RLEB -> RLEB -> Bool
<= :: RLEB -> RLEB -> Bool
$c<= :: RLEB -> RLEB -> Bool
< :: RLEB -> RLEB -> Bool
$c< :: RLEB -> RLEB -> Bool
compare :: RLEB -> RLEB -> Ordering
$ccompare :: RLEB -> RLEB -> Ordering
Ord,Int -> RLEB -> ShowS
[RLEB] -> ShowS
RLEB -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RLEB] -> ShowS
$cshowList :: [RLEB] -> ShowS
show :: RLEB -> String
$cshow :: RLEB -> String
showsPrec :: Int -> RLEB -> ShowS
$cshowsPrec :: Int -> RLEB -> ShowS
Show,ReadPrec [RLEB]
ReadPrec RLEB
Int -> ReadS RLEB
ReadS [RLEB]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RLEB]
$creadListPrec :: ReadPrec [RLEB]
readPrec :: ReadPrec RLEB
$creadPrec :: ReadPrec RLEB
readList :: ReadS [RLEB]
$creadList :: ReadS [RLEB]
readsPrec :: Int -> ReadS RLEB
$creadsPrec :: Int -> ReadS RLEB
Read,forall x. Rep RLEB x -> RLEB
forall x. RLEB -> Rep RLEB x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep RLEB x -> RLEB
$cfrom :: forall x. RLEB -> Rep RLEB x
Generic)

-- | Basic RLE ('Text') data type.
newtype RLET = RLET (Seq (Maybe Text))
  deriving (RLET -> RLET -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RLET -> RLET -> Bool
$c/= :: RLET -> RLET -> Bool
== :: RLET -> RLET -> Bool
$c== :: RLET -> RLET -> Bool
Eq,Eq RLET
RLET -> RLET -> Bool
RLET -> RLET -> Ordering
RLET -> RLET -> RLET
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RLET -> RLET -> RLET
$cmin :: RLET -> RLET -> RLET
max :: RLET -> RLET -> RLET
$cmax :: RLET -> RLET -> RLET
>= :: RLET -> RLET -> Bool
$c>= :: RLET -> RLET -> Bool
> :: RLET -> RLET -> Bool
$c> :: RLET -> RLET -> Bool
<= :: RLET -> RLET -> Bool
$c<= :: RLET -> RLET -> Bool
< :: RLET -> RLET -> Bool
$c< :: RLET -> RLET -> Bool
compare :: RLET -> RLET -> Ordering
$ccompare :: RLET -> RLET -> Ordering
Ord,Int -> RLET -> ShowS
[RLET] -> ShowS
RLET -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RLET] -> ShowS
$cshowList :: [RLET] -> ShowS
show :: RLET -> String
$cshow :: RLET -> String
showsPrec :: Int -> RLET -> ShowS
$cshowsPrec :: Int -> RLET -> ShowS
Show,ReadPrec [RLET]
ReadPrec RLET
Int -> ReadS RLET
ReadS [RLET]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RLET]
$creadListPrec :: ReadPrec [RLET]
readPrec :: ReadPrec RLET
$creadPrec :: ReadPrec RLET
readList :: ReadS [RLET]
$creadList :: ReadS [RLET]
readsPrec :: Int -> ReadS RLET
$creadsPrec :: Int -> ReadS RLET
Read,forall x. Rep RLET x -> RLET
forall x. RLET -> Rep RLET x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep RLET x -> RLET
$cfrom :: forall x. RLET -> Rep RLET x
Generic)

{-------------------}


{-toRLE (ByteString) functions.-}

-- | Abstract 'RLESeqB' type utilizing a 'Seq'.
type RLESeqB = Seq (Maybe ByteString)

-- | Abstract data type representing a 'RLESeqB' in the (strict) ST monad.
type STRLESeqB s a = STRef s RLESeqB

-- | State function to push 'RLESeqB' data into stack.
pushSTRLESeqB :: STRLESeqB s (Maybe ByteString)
              -> Maybe ByteString
              -> ST s ()
pushSTRLESeqB :: forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
s Maybe ByteString
Nothing  = do
  Seq (Maybe ByteString)
s2 <- forall s a. STRef s a -> ST s a
readSTRef STRLESeqB s (Maybe ByteString)
s
  forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLESeqB s (Maybe ByteString)
s (Seq (Maybe ByteString)
s2 forall a. Seq a -> a -> Seq a
DS.|> forall a. Maybe a
Nothing)
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
s (Just ByteString
e) = do
  Seq (Maybe ByteString)
s2 <- forall s a. STRef s a -> ST s a
readSTRef STRLESeqB s (Maybe ByteString)
s
  forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLESeqB s (Maybe ByteString)
s (Seq (Maybe ByteString)
s2 forall a. Seq a -> a -> Seq a
DS.|> forall a. a -> Maybe a
Just ByteString
e)

-- | State function to create empty 'STRLESeqB' type.
emptySTRLESeqB :: ST s (STRLESeqB s a)
emptySTRLESeqB :: forall s a. ST s (STRLESeqB s a)
emptySTRLESeqB = forall a s. a -> ST s (STRef s a)
newSTRef forall a. Seq a
DS.empty

-- | Abstract 'STRLETempB' and associated state type.
type STRLETempB s a = STRef s (Maybe ByteString)

-- | State function to update 'STRLETempB'.
updateSTRLETempB :: STRLETempB s (Maybe ByteString)
                 -> Maybe ByteString
                 -> ST s ()
updateSTRLETempB :: forall s.
STRLETempB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
updateSTRLETempB STRLETempB s (Maybe ByteString)
s Maybe ByteString
Nothing  = forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLETempB s (Maybe ByteString)
s forall a. Maybe a
Nothing
updateSTRLETempB STRLETempB s (Maybe ByteString)
s (Just ByteString
e) = forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLETempB s (Maybe ByteString)
s (forall a. a -> Maybe a
Just ByteString
e)

-- | State function to create empty 'STRLETempB' type.
emptySTRLETempB :: ST s (STRLETempB s a)
emptySTRLETempB :: forall s a. ST s (STRLETempB s a)
emptySTRLETempB = forall a s. a -> ST s (STRef s a)
newSTRef (forall a. a -> Maybe a
Just ByteString
BS.empty)

-- | Abstract 'STRLECounterB' state type.
type STRLECounterB s a = STRef s Int

-- | State function to update 'STRLECounterB'.
updateSTRLECounterB :: STRLECounterB s Int
                    -> Int
                    -> ST s ()
updateSTRLECounterB :: forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterB STRLECounterB s Int
s Int
e = forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLECounterB s Int
s Int
e

-- | State function to create empty 'STRLECounterB' type.
emptySTRLECounterB :: ST s (STRLECounterB s Int)
emptySTRLECounterB :: forall s. ST s (STRLECounterB s Int)
emptySTRLECounterB = forall a s. a -> ST s (STRef s a)
newSTRef (-Int
1)

-- | Strict state monad function.
seqToRLEB :: RLESeqB
          -> ST s RLESeqB
seqToRLEB :: forall s. Seq (Maybe ByteString) -> ST s (Seq (Maybe ByteString))
seqToRLEB Seq (Maybe ByteString)
DS.Empty      = do
  STRLESeqB s Any
brleseqstackempty  <- forall s a. ST s (STRLESeqB s a)
emptySTRLESeqB
  Seq (Maybe ByteString)
brleseqstackemptyr <- forall s a. STRef s a -> ST s a
readSTRef STRLESeqB s Any
brleseqstackempty
  forall (m :: * -> *) a. Monad m => a -> m a
return Seq (Maybe ByteString)
brleseqstackemptyr
seqToRLEB (Maybe ByteString
x DS.:<| Seq (Maybe ByteString)
xs) = do
  STRLESeqB s Any
brleseqstack     <- forall s a. ST s (STRLESeqB s a)
emptySTRLESeqB
  STRLECounterB s Int
brlecounterstack <- forall s. ST s (STRLECounterB s Int)
emptySTRLECounterB
  STRLETempB s Any
brletempstack    <- forall s a. ST s (STRLETempB s a)
emptySTRLETempB
  forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterB STRLECounterB s Int
brlecounterstack
                      Int
1 
  forall s.
STRLETempB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
updateSTRLETempB STRLETempB s Any
brletempstack
                   Maybe ByteString
x
  forall {s}.
Seq (Maybe ByteString)
-> STRLESeqB s (Maybe ByteString)
-> STRef s Int
-> STRef s (Maybe ByteString)
-> ST s ()
iRLEB Seq (Maybe ByteString)
xs
        STRLESeqB s Any
brleseqstack
        STRLECounterB s Int
brlecounterstack
        STRLETempB s Any
brletempstack
  Seq (Maybe ByteString)
brleseqstackr <- forall s a. STRef s a -> ST s a
readSTRef STRLESeqB s Any
brleseqstack
  forall (m :: * -> *) a. Monad m => a -> m a
return Seq (Maybe ByteString)
brleseqstackr
    where
      iRLEB :: Seq (Maybe ByteString)
-> STRLESeqB s (Maybe ByteString)
-> STRef s Int
-> STRef s (Maybe ByteString)
-> ST s ()
iRLEB Seq (Maybe ByteString)
DS.Empty      STRLESeqB s (Maybe ByteString)
brless STRef s Int
brlecs STRef s (Maybe ByteString)
brlets = do
        Int
cbrlecs <- forall s a. STRef s a -> ST s a
readSTRef STRef s Int
brlecs
        Maybe ByteString
cbrlets <- forall s a. STRef s a -> ST s a
readSTRef STRef s (Maybe ByteString)
brlets
        forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
brless
                      (forall a. a -> Maybe a
Just      forall a b. (a -> b) -> a -> b
$
                       String -> ByteString
BSC8.pack forall a b. (a -> b) -> a -> b
$
                       forall a. Show a => a -> String
show Int
cbrlecs)
        forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
brless
                      Maybe ByteString
cbrlets
        forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      iRLEB (Maybe ByteString
y DS.:<| Seq (Maybe ByteString)
ys) STRLESeqB s (Maybe ByteString)
brless STRef s Int
brlecs STRef s (Maybe ByteString)
brlets = do
        Int
cbrlecs <- forall s a. STRef s a -> ST s a
readSTRef STRef s Int
brlecs
        Maybe ByteString
cbrlets <- forall s a. STRef s a -> ST s a
readSTRef STRef s (Maybe ByteString)
brlets
        if | forall a. Maybe a -> Bool
isNothing Maybe ByteString
y
           -> do forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
brless
                               (forall a. a -> Maybe a
Just      forall a b. (a -> b) -> a -> b
$
                                String -> ByteString
BSC8.pack forall a b. (a -> b) -> a -> b
$
                                forall a. Show a => a -> String
show Int
cbrlecs)
                 forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
brless
                               Maybe ByteString
cbrlets 
                 forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
brless
                               (forall a. a -> Maybe a
Just      forall a b. (a -> b) -> a -> b
$
                                String -> ByteString
BSC8.pack forall a b. (a -> b) -> a -> b
$
                                forall a. Show a => a -> String
show (Int
1 :: Int))
                 forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
brless
                               forall a. Maybe a
Nothing
                 forall s.
STRLETempB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
updateSTRLETempB STRef s (Maybe ByteString)
brlets
                                  forall a. Maybe a
Nothing             
                 Seq (Maybe ByteString)
-> STRLESeqB s (Maybe ByteString)
-> STRef s Int
-> STRef s (Maybe ByteString)
-> ST s ()
iRLEB Seq (Maybe ByteString)
ys
                       STRLESeqB s (Maybe ByteString)
brless
                       STRef s Int
brlecs
                       STRef s (Maybe ByteString)
brlets
           | forall a. Maybe a -> Bool
isNothing Maybe ByteString
cbrlets
           -> do forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterB STRef s Int
brlecs
                                     Int
1
                 forall s.
STRLETempB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
updateSTRLETempB STRef s (Maybe ByteString)
brlets
                                  Maybe ByteString
y
                 Seq (Maybe ByteString)
-> STRLESeqB s (Maybe ByteString)
-> STRef s Int
-> STRef s (Maybe ByteString)
-> ST s ()
iRLEB Seq (Maybe ByteString)
ys
                       STRLESeqB s (Maybe ByteString)
brless
                       STRef s Int
brlecs
                       STRef s (Maybe ByteString)
brlets
           | forall a. HasCallStack => Maybe a -> a
fromJust Maybe ByteString
cbrlets forall a. Eq a => a -> a -> Bool
== forall a. HasCallStack => Maybe a -> a
fromJust Maybe ByteString
y
           -> do forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterB STRef s Int
brlecs
                                     (Int
cbrlecs forall a. Num a => a -> a -> a
+ Int
1)
                 Seq (Maybe ByteString)
-> STRLESeqB s (Maybe ByteString)
-> STRef s Int
-> STRef s (Maybe ByteString)
-> ST s ()
iRLEB Seq (Maybe ByteString)
ys
                       STRLESeqB s (Maybe ByteString)
brless
                       STRef s Int
brlecs
                       STRef s (Maybe ByteString)
brlets
           | Bool
otherwise
           -> do forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
brless
                               (forall a. a -> Maybe a
Just      forall a b. (a -> b) -> a -> b
$
                                String -> ByteString
BSC8.pack forall a b. (a -> b) -> a -> b
$
                                forall a. Show a => a -> String
show Int
cbrlecs)
                 forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushSTRLESeqB STRLESeqB s (Maybe ByteString)
brless
                               Maybe ByteString
cbrlets
                 forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterB STRef s Int
brlecs
                                     Int
1
                 forall s.
STRLETempB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
updateSTRLETempB STRef s (Maybe ByteString)
brlets
                                  Maybe ByteString
y
                 Seq (Maybe ByteString)
-> STRLESeqB s (Maybe ByteString)
-> STRef s Int
-> STRef s (Maybe ByteString)
-> ST s ()
iRLEB Seq (Maybe ByteString)
ys
                       STRLESeqB s (Maybe ByteString)
brless
                       STRef s Int
brlecs
                       STRef s (Maybe ByteString)
brlets

{-------------------------------}


{-toRLE (Text) functions.-}

-- | Abstract 'RLESeqT' type utilizing a 'Seq'.
type RLESeqT = Seq (Maybe Text)

-- | Abstract data type representing a 'RLESeqT' in the (strict) ST monad.
type STRLESeqT s a = STRef s RLESeqT

-- | State function to push 'RLESeqT' data into stack.
pushSTRLESeqT :: STRLESeqT s (Maybe Text)
              -> (Maybe Text)
              -> ST s ()
pushSTRLESeqT :: forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushSTRLESeqT STRLESeqT s (Maybe Text)
s Maybe Text
Nothing  = do
  Seq (Maybe Text)
s2 <- forall s a. STRef s a -> ST s a
readSTRef STRLESeqT s (Maybe Text)
s
  forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLESeqT s (Maybe Text)
s (Seq (Maybe Text)
s2 forall a. Seq a -> a -> Seq a
DS.|> forall a. Maybe a
Nothing)
pushSTRLESeqT STRLESeqT s (Maybe Text)
s (Just Text
e) = do
  Seq (Maybe Text)
s2 <- forall s a. STRef s a -> ST s a
readSTRef STRLESeqT s (Maybe Text)
s
  forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLESeqT s (Maybe Text)
s (Seq (Maybe Text)
s2 forall a. Seq a -> a -> Seq a
DS.|> forall a. a -> Maybe a
Just Text
e)

-- | State function to create empty 'STRLESeqT' type.
emptySTRLESeqT :: ST s (STRLESeqT s a)
emptySTRLESeqT :: forall s a. ST s (STRLESeqT s a)
emptySTRLESeqT = forall a s. a -> ST s (STRef s a)
newSTRef forall a. Seq a
DS.empty

-- | Abstract 'STRLETempT' state type.
type STRLETempT s a = STRef s (Maybe Text)

-- | State function to update 'STRLETempT'.
updateSTRLETempT :: STRLETempT s (Maybe Text)
                 -> (Maybe Text)
                 -> ST s ()
updateSTRLETempT :: forall s. STRLETempT s (Maybe Text) -> Maybe Text -> ST s ()
updateSTRLETempT STRLETempT s (Maybe Text)
s Maybe Text
Nothing  = forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLETempT s (Maybe Text)
s forall a. Maybe a
Nothing
updateSTRLETempT STRLETempT s (Maybe Text)
s (Just Text
e) = forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLETempT s (Maybe Text)
s (forall a. a -> Maybe a
Just Text
e)

-- | State function to create empty 'STRLETempT' type.
emptySTRLETempT :: ST s (STRLETempT s a)
emptySTRLETempT :: forall s a. ST s (STRLETempT s a)
emptySTRLETempT = forall a s. a -> ST s (STRef s a)
newSTRef (forall a. a -> Maybe a
Just Text
DText.empty)

-- | Abstract 'STRLECounterT' and associated state type.
type STRLECounterT s a = STRef s Int

-- | State function to update 'STRLECounterT'.
updateSTRLECounterT :: STRLECounterT s Int
                    -> Int
                    -> ST s ()
updateSTRLECounterT :: forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterT STRLECounterT s Int
s Int
e = forall s a. STRef s a -> a -> ST s ()
writeSTRef STRLECounterT s Int
s Int
e

-- | State function to create empty 'STRLECounterT' type.
emptySTRLECounterT :: ST s (STRLECounterT s Int)
emptySTRLECounterT :: forall s. ST s (STRLECounterB s Int)
emptySTRLECounterT = forall a s. a -> ST s (STRef s a)
newSTRef (-Int
1)

-- | Strict state monad function.
seqToRLET :: RLESeqT
          -> ST s RLESeqT
seqToRLET :: forall s. Seq (Maybe Text) -> ST s (Seq (Maybe Text))
seqToRLET Seq (Maybe Text)
DS.Empty      = do
  STRLESeqT s Any
trleseqstackempty  <- forall s a. ST s (STRLESeqT s a)
emptySTRLESeqT
  Seq (Maybe Text)
trleseqstackemptyr <- forall s a. STRef s a -> ST s a
readSTRef STRLESeqT s Any
trleseqstackempty
  forall (m :: * -> *) a. Monad m => a -> m a
return Seq (Maybe Text)
trleseqstackemptyr
seqToRLET (Maybe Text
x DS.:<| Seq (Maybe Text)
xs) = do
  STRLESeqT s Any
trleseqstack     <- forall s a. ST s (STRLESeqT s a)
emptySTRLESeqT
  STRLECounterT s Int
trlecounterstack <- forall s. ST s (STRLECounterB s Int)
emptySTRLECounterT
  STRLETempT s Any
trletempstack    <- forall s a. ST s (STRLETempT s a)
emptySTRLETempT
  forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterT STRLECounterT s Int
trlecounterstack
                      Int
1
  forall s. STRLETempT s (Maybe Text) -> Maybe Text -> ST s ()
updateSTRLETempT STRLETempT s Any
trletempstack
                   Maybe Text
x
  forall {s}.
Seq (Maybe Text)
-> STRLESeqT s (Maybe Text)
-> STRef s Int
-> STRef s (Maybe Text)
-> ST s ()
iRLET Seq (Maybe Text)
xs
        STRLESeqT s Any
trleseqstack
        STRLECounterT s Int
trlecounterstack
        STRLETempT s Any
trletempstack
  Seq (Maybe Text)
trleseqstackr <- forall s a. STRef s a -> ST s a
readSTRef STRLESeqT s Any
trleseqstack
  forall (m :: * -> *) a. Monad m => a -> m a
return Seq (Maybe Text)
trleseqstackr
    where
      iRLET :: Seq (Maybe Text)
-> STRLESeqT s (Maybe Text)
-> STRef s Int
-> STRef s (Maybe Text)
-> ST s ()
iRLET Seq (Maybe Text)
DS.Empty      STRLESeqT s (Maybe Text)
trless STRef s Int
trlecs STRef s (Maybe Text)
trlets = do
        Int
ctrlecs <- forall s a. STRef s a -> ST s a
readSTRef STRef s Int
trlecs
        Maybe Text
ctrlets <- forall s a. STRef s a -> ST s a
readSTRef STRef s (Maybe Text)
trlets
        forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushSTRLESeqT STRLESeqT s (Maybe Text)
trless
                      (forall a. a -> Maybe a
Just       forall a b. (a -> b) -> a -> b
$
                       String -> Text
DText.pack forall a b. (a -> b) -> a -> b
$
                       forall a. Show a => a -> String
show Int
ctrlecs)
        forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushSTRLESeqT STRLESeqT s (Maybe Text)
trless
                      Maybe Text
ctrlets 
        forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      iRLET (Maybe Text
y DS.:<| Seq (Maybe Text)
ys) STRLESeqT s (Maybe Text)
trless STRef s Int
trlecs STRef s (Maybe Text)
trlets = do
        Int
ctrlecs <- forall s a. STRef s a -> ST s a
readSTRef STRef s Int
trlecs
        Maybe Text
ctrlets <- forall s a. STRef s a -> ST s a
readSTRef STRef s (Maybe Text)
trlets
        if | forall a. Maybe a -> Bool
isNothing Maybe Text
y
           -> do forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushSTRLESeqT STRLESeqT s (Maybe Text)
trless
                               (forall a. a -> Maybe a
Just       forall a b. (a -> b) -> a -> b
$
                                String -> Text
DText.pack forall a b. (a -> b) -> a -> b
$
                                forall a. Show a => a -> String
show Int
ctrlecs)
                 forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushSTRLESeqT STRLESeqT s (Maybe Text)
trless
                               Maybe Text
ctrlets
                 forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushSTRLESeqT STRLESeqT s (Maybe Text)
trless
                               (forall a. a -> Maybe a
Just       forall a b. (a -> b) -> a -> b
$
                                String -> Text
DText.pack forall a b. (a -> b) -> a -> b
$
                                forall a. Show a => a -> String
show (Int
1 :: Int))
                 forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushSTRLESeqT STRLESeqT s (Maybe Text)
trless
                               forall a. Maybe a
Nothing
                 forall s. STRLETempT s (Maybe Text) -> Maybe Text -> ST s ()
updateSTRLETempT STRef s (Maybe Text)
trlets
                                  forall a. Maybe a
Nothing
                 Seq (Maybe Text)
-> STRLESeqT s (Maybe Text)
-> STRef s Int
-> STRef s (Maybe Text)
-> ST s ()
iRLET Seq (Maybe Text)
ys
                       STRLESeqT s (Maybe Text)
trless
                       STRef s Int
trlecs
                       STRef s (Maybe Text)
trlets
           | forall a. Maybe a -> Bool
isNothing Maybe Text
ctrlets
           -> do forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterT STRef s Int
trlecs
                                     Int
1
                 forall s. STRLETempT s (Maybe Text) -> Maybe Text -> ST s ()
updateSTRLETempT STRef s (Maybe Text)
trlets
                                  Maybe Text
y
                 Seq (Maybe Text)
-> STRLESeqT s (Maybe Text)
-> STRef s Int
-> STRef s (Maybe Text)
-> ST s ()
iRLET Seq (Maybe Text)
ys
                       STRLESeqT s (Maybe Text)
trless
                       STRef s Int
trlecs
                       STRef s (Maybe Text)
trlets
           | forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
ctrlets forall a. Eq a => a -> a -> Bool
== forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
y
           -> do forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterT STRef s Int
trlecs
                                     (Int
ctrlecs forall a. Num a => a -> a -> a
+ Int
1)
                 Seq (Maybe Text)
-> STRLESeqT s (Maybe Text)
-> STRef s Int
-> STRef s (Maybe Text)
-> ST s ()
iRLET Seq (Maybe Text)
ys
                       STRLESeqT s (Maybe Text)
trless
                       STRef s Int
trlecs
                       STRef s (Maybe Text)
trlets
           | Bool
otherwise
           -> do forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushSTRLESeqT STRLESeqT s (Maybe Text)
trless
                               (forall a. a -> Maybe a
Just       forall a b. (a -> b) -> a -> b
$
                                String -> Text
DText.pack forall a b. (a -> b) -> a -> b
$
                                forall a. Show a => a -> String
show Int
ctrlecs)
                 forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushSTRLESeqT STRLESeqT s (Maybe Text)
trless
                               Maybe Text
ctrlets
                 forall s. STRLECounterB s Int -> Int -> ST s ()
updateSTRLECounterT STRef s Int
trlecs
                                     Int
1
                 forall s. STRLETempT s (Maybe Text) -> Maybe Text -> ST s ()
updateSTRLETempT STRef s (Maybe Text)
trlets
                                  Maybe Text
y
                 Seq (Maybe Text)
-> STRLESeqT s (Maybe Text)
-> STRef s Int
-> STRef s (Maybe Text)
-> ST s ()
iRLET Seq (Maybe Text)
ys
                       STRLESeqT s (Maybe Text)
trless
                       STRef s Int
trlecs
                       STRef s (Maybe Text)
trlets

{-------------------------}


{-fromRLE (ByteString) functions.-}

-- | Abstract 'FRLESeqB' type utilizing a 'Seq'.
type FRLESeqB = Seq (Maybe ByteString)

-- | Abstract data type representing a 'FRLESeqB' in the (strict) ST monad.
type FSTRLESeqB s a = STRef s FRLESeqB

-- | State function to push 'FRLESeqB' data into stack.
pushFSTRLESeqB :: FSTRLESeqB s (Maybe ByteString)
               -> (Maybe ByteString)
               -> ST s ()
pushFSTRLESeqB :: forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushFSTRLESeqB FSTRLESeqB s (Maybe ByteString)
s Maybe ByteString
Nothing  = do
  Seq (Maybe ByteString)
s2 <- forall s a. STRef s a -> ST s a
readSTRef FSTRLESeqB s (Maybe ByteString)
s
  forall s a. STRef s a -> a -> ST s ()
writeSTRef FSTRLESeqB s (Maybe ByteString)
s (Seq (Maybe ByteString)
s2 forall a. Seq a -> a -> Seq a
DS.|> forall a. Maybe a
Nothing)
pushFSTRLESeqB FSTRLESeqB s (Maybe ByteString)
s (Just ByteString
e) = do
  Seq (Maybe ByteString)
s2 <- forall s a. STRef s a -> ST s a
readSTRef FSTRLESeqB s (Maybe ByteString)
s
  forall s a. STRef s a -> a -> ST s ()
writeSTRef FSTRLESeqB s (Maybe ByteString)
s (Seq (Maybe ByteString)
s2 forall a. Seq a -> a -> Seq a
DS.|> forall a. a -> Maybe a
Just ByteString
e)

-- | State function to create empty 'FSTRLESeqB' type.
emptyFSTRLESeqB :: ST s (FSTRLESeqB s a)
emptyFSTRLESeqB :: forall s a. ST s (STRLESeqB s a)
emptyFSTRLESeqB = forall a s. a -> ST s (STRef s a)
newSTRef forall a. Seq a
DS.empty

-- | Strict state monad function.
seqFromRLEB :: RLEB
            -> ST s FRLESeqB
seqFromRLEB :: forall s. RLEB -> ST s (Seq (Maybe ByteString))
seqFromRLEB (RLEB Seq (Maybe ByteString)
DS.Empty) = do
  FSTRLESeqB s Any
fbrleseqstackempty  <- forall s a. ST s (STRLESeqB s a)
emptyFSTRLESeqB
  Seq (Maybe ByteString)
fbrleseqstackemptyr <- forall s a. STRef s a -> ST s a
readSTRef FSTRLESeqB s Any
fbrleseqstackempty
  forall (m :: * -> *) a. Monad m => a -> m a
return Seq (Maybe ByteString)
fbrleseqstackemptyr
seqFromRLEB RLEB
xs              = do
  FSTRLESeqB s Any
fbrleseqstack <- forall s a. ST s (STRLESeqB s a)
emptySTRLESeqB
  let rlebseq :: Seq (Maybe ByteString)
rlebseq = (\(RLEB Seq (Maybe ByteString)
b) -> Seq (Maybe ByteString)
b) RLEB
xs
  forall {s}.
Seq (Maybe ByteString)
-> FSTRLESeqB s (Maybe ByteString) -> ST s ()
iFRLEB Seq (Maybe ByteString)
rlebseq
         FSTRLESeqB s Any
fbrleseqstack
  Seq (Maybe ByteString)
fbrleseqstackr <- forall s a. STRef s a -> ST s a
readSTRef FSTRLESeqB s Any
fbrleseqstack
  forall (m :: * -> *) a. Monad m => a -> m a
return Seq (Maybe ByteString)
fbrleseqstackr
    where
      iFRLEB :: Seq (Maybe ByteString)
-> FSTRLESeqB s (Maybe ByteString) -> ST s ()
iFRLEB (Maybe ByteString
y1 DS.:<| Maybe ByteString
y2 DS.:<| Seq (Maybe ByteString)
DS.Empty) FSTRLESeqB s (Maybe ByteString)
fbrless =
        if | forall a. Maybe a -> Bool
isJust Maybe ByteString
y1    Bool -> Bool -> Bool
&&
             forall a. Maybe a -> Bool
isNothing Maybe ByteString
y2
           -> do forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushFSTRLESeqB FSTRLESeqB s (Maybe ByteString)
fbrless
                                forall a. Maybe a
Nothing
                 forall (f :: * -> *) a. Applicative f => a -> f a
pure () 
           | Bool
otherwise
           -> do let y1' :: Int
y1' = forall a. Read a => String -> a
read        forall a b. (a -> b) -> a -> b
$
                           ByteString -> String
BSC8.unpack forall a b. (a -> b) -> a -> b
$
                           forall a. HasCallStack => Maybe a -> a
fromJust Maybe ByteString
y1 :: Int
                 let y2' :: ByteString
y2' = forall a. HasCallStack => Maybe a -> a
fromJust Maybe ByteString
y2
                 forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
CM.replicateM_ Int
y1'
                                (forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushFSTRLESeqB FSTRLESeqB s (Maybe ByteString)
fbrless
                                                (forall a. a -> Maybe a
Just ByteString
y2'))
                 forall (f :: * -> *) a. Applicative f => a -> f a
pure () 
      iFRLEB (Maybe ByteString
y1 DS.:<| Maybe ByteString
y2 DS.:<| Seq (Maybe ByteString)
ys)       FSTRLESeqB s (Maybe ByteString)
fbrless =
        if | forall a. Maybe a -> Bool
isJust Maybe ByteString
y1     Bool -> Bool -> Bool
&&
             forall a. Maybe a -> Bool
isNothing Maybe ByteString
y2
           -> do forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushFSTRLESeqB FSTRLESeqB s (Maybe ByteString)
fbrless
                                forall a. Maybe a
Nothing
                 Seq (Maybe ByteString)
-> FSTRLESeqB s (Maybe ByteString) -> ST s ()
iFRLEB Seq (Maybe ByteString)
ys
                        FSTRLESeqB s (Maybe ByteString)
fbrless
           | Bool
otherwise
           -> do let y1' :: Int
y1' = forall a. Read a => String -> a
read        forall a b. (a -> b) -> a -> b
$
                           ByteString -> String
BSC8.unpack forall a b. (a -> b) -> a -> b
$
                           forall a. HasCallStack => Maybe a -> a
fromJust Maybe ByteString
y1 :: Int
                 let y2' :: ByteString
y2' = forall a. HasCallStack => Maybe a -> a
fromJust Maybe ByteString
y2
                 forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
CM.replicateM_ Int
y1'
                                (forall s.
STRLESeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
pushFSTRLESeqB FSTRLESeqB s (Maybe ByteString)
fbrless
                                                (forall a. a -> Maybe a
Just ByteString
y2'))
                 Seq (Maybe ByteString)
-> FSTRLESeqB s (Maybe ByteString) -> ST s ()
iFRLEB Seq (Maybe ByteString)
ys
                        FSTRLESeqB s (Maybe ByteString)
fbrless 
      iFRLEB (DSI.Seq FingerTree (Elem (Maybe ByteString))
EmptyT)               FSTRLESeqB s (Maybe ByteString)
_       = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      iFRLEB (DSI.Seq (Single Elem (Maybe ByteString)
_))           FSTRLESeqB s (Maybe ByteString)
_       = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      iFRLEB (DSI.Seq (Deep Int
_ Digit (Elem (Maybe ByteString))
_ FingerTree (Node (Elem (Maybe ByteString)))
_ Digit (Elem (Maybe ByteString))
_))       FSTRLESeqB s (Maybe ByteString)
_       = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

{---------------------------------}


{-fromRLE (Text) functions.-}

-- | Abstract 'FRLESeqT' type utilizing a 'Seq'.
type FRLESeqT = Seq (Maybe Text)

-- | Abstract data type representing a 'FRLESeqT' in the (strict) ST monad.
type FSTRLESeqT s a = STRef s FRLESeqT

-- | State function to push 'FSTRLESeqT' data into stack.
pushFSTRLESeqT :: FSTRLESeqT s (Maybe Text)
               -> (Maybe Text)
               -> ST s ()
pushFSTRLESeqT :: forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushFSTRLESeqT FSTRLESeqT s (Maybe Text)
s Maybe Text
Nothing  = do
  Seq (Maybe Text)
s2 <- forall s a. STRef s a -> ST s a
readSTRef FSTRLESeqT s (Maybe Text)
s
  forall s a. STRef s a -> a -> ST s ()
writeSTRef FSTRLESeqT s (Maybe Text)
s (Seq (Maybe Text)
s2 forall a. Seq a -> a -> Seq a
DS.|> forall a. Maybe a
Nothing)
pushFSTRLESeqT FSTRLESeqT s (Maybe Text)
s (Just Text
e) = do
  Seq (Maybe Text)
s2 <- forall s a. STRef s a -> ST s a
readSTRef FSTRLESeqT s (Maybe Text)
s
  forall s a. STRef s a -> a -> ST s ()
writeSTRef FSTRLESeqT s (Maybe Text)
s (Seq (Maybe Text)
s2 forall a. Seq a -> a -> Seq a
DS.|> forall a. a -> Maybe a
Just Text
e)

-- | State function to create empty 'FSTRLESeqT' type.
emptyFSTRLESeqT :: ST s (FSTRLESeqT s a)
emptyFSTRLESeqT :: forall s a. ST s (STRLESeqT s a)
emptyFSTRLESeqT = forall a s. a -> ST s (STRef s a)
newSTRef forall a. Seq a
DS.empty

-- | Strict state monad function.
seqFromRLET :: RLET ->
               ST s FRLESeqT
seqFromRLET :: forall s. RLET -> ST s (Seq (Maybe Text))
seqFromRLET (RLET Seq (Maybe Text)
DS.Empty) = do
  FSTRLESeqT s Any
ftrleseqstackempty  <- forall s a. ST s (STRLESeqT s a)
emptyFSTRLESeqT
  Seq (Maybe Text)
ftrleseqstackemptyr <- forall s a. STRef s a -> ST s a
readSTRef FSTRLESeqT s Any
ftrleseqstackempty
  forall (m :: * -> *) a. Monad m => a -> m a
return Seq (Maybe Text)
ftrleseqstackemptyr
seqFromRLET RLET
xs              = do
  FSTRLESeqT s Any
ftrleseqstack <- forall s a. ST s (STRLESeqT s a)
emptySTRLESeqT
  let rletseq :: Seq (Maybe Text)
rletseq = (\(RLET Seq (Maybe Text)
t) -> Seq (Maybe Text)
t) RLET
xs
  forall {s}.
Seq (Maybe Text) -> FSTRLESeqT s (Maybe Text) -> ST s ()
iFRLET Seq (Maybe Text)
rletseq
         FSTRLESeqT s Any
ftrleseqstack
  Seq (Maybe Text)
ftrleseqstackr <- forall s a. STRef s a -> ST s a
readSTRef FSTRLESeqT s Any
ftrleseqstack
  forall (m :: * -> *) a. Monad m => a -> m a
return Seq (Maybe Text)
ftrleseqstackr
    where
      iFRLET :: Seq (Maybe Text) -> FSTRLESeqT s (Maybe Text) -> ST s ()
iFRLET (Maybe Text
y1 DS.:<| Maybe Text
y2 DS.:<| Seq (Maybe Text)
DS.Empty) FSTRLESeqT s (Maybe Text)
ftrless =
        if | forall a. Maybe a -> Bool
isJust Maybe Text
y1    Bool -> Bool -> Bool
&&
             forall a. Maybe a -> Bool
isNothing Maybe Text
y2
           -> do forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushFSTRLESeqT FSTRLESeqT s (Maybe Text)
ftrless
                                forall a. Maybe a
Nothing
                 forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
           | Bool
otherwise
           -> do let y1' :: Int
y1' = forall a. Read a => String -> a
read         forall a b. (a -> b) -> a -> b
$
                           Text -> String
DText.unpack forall a b. (a -> b) -> a -> b
$
                           forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
y1 :: Int
                 let y2' :: Text
y2' = forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
y2
                 forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
CM.replicateM_ Int
y1'
                                (forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushFSTRLESeqT FSTRLESeqT s (Maybe Text)
ftrless
                                                (forall a. a -> Maybe a
Just Text
y2'))
                 forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      iFRLET (Maybe Text
y1 DS.:<| Maybe Text
y2 DS.:<| Seq (Maybe Text)
ys)       FSTRLESeqT s (Maybe Text)
ftrless =
        if | forall a. Maybe a -> Bool
isJust Maybe Text
y1     Bool -> Bool -> Bool
&&
             forall a. Maybe a -> Bool
isNothing Maybe Text
y2
           -> do forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushFSTRLESeqT FSTRLESeqT s (Maybe Text)
ftrless
                                forall a. Maybe a
Nothing
                 Seq (Maybe Text) -> FSTRLESeqT s (Maybe Text) -> ST s ()
iFRLET Seq (Maybe Text)
ys
                        FSTRLESeqT s (Maybe Text)
ftrless
           | Bool
otherwise
           -> do let y1' :: Int
y1' = forall a. Read a => String -> a
read         forall a b. (a -> b) -> a -> b
$
                           Text -> String
DText.unpack forall a b. (a -> b) -> a -> b
$
                           forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
y1 :: Int
                 let y2' :: Text
y2' = forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
y2
                 forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
CM.replicateM_ Int
y1'
                                (forall s. STRLESeqT s (Maybe Text) -> Maybe Text -> ST s ()
pushFSTRLESeqT FSTRLESeqT s (Maybe Text)
ftrless
                                                (forall a. a -> Maybe a
Just Text
y2'))
                 Seq (Maybe Text) -> FSTRLESeqT s (Maybe Text) -> ST s ()
iFRLET Seq (Maybe Text)
ys
                        FSTRLESeqT s (Maybe Text)
ftrless
      iFRLET (DSI.Seq FingerTree (Elem (Maybe Text))
EmptyT)               FSTRLESeqT s (Maybe Text)
_       = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      iFRLET (DSI.Seq (Single Elem (Maybe Text)
_))           FSTRLESeqT s (Maybe Text)
_       = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      iFRLET (DSI.Seq (Deep Int
_ Digit (Elem (Maybe Text))
_ FingerTree (Node (Elem (Maybe Text)))
_ Digit (Elem (Maybe Text))
_))       FSTRLESeqT s (Maybe Text)
_       = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

{---------------------------}