packages feed

text-compression 0.1.0.9 → 0.1.0.10

raw patch · 8 files changed

+985/−60 lines, 8 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Data.MTF: bytestringBWTFromMTFB :: MTFB -> BWT ByteString
+ Data.MTF: bytestringBWTFromMTFT :: MTFT -> BWT ByteString
+ Data.MTF: bytestringBWTToMTFB :: BWT Word8 -> MTFB
+ Data.MTF: bytestringBWTToMTFT :: BWT Word8 -> MTFT
+ Data.MTF: bytestringFromBWTFromMTFB :: MTFB -> ByteString
+ Data.MTF: bytestringFromBWTFromMTFT :: MTFT -> ByteString
+ Data.MTF: bytestringFromMTFB :: MTFB -> Seq (Maybe ByteString)
+ Data.MTF: bytestringFromMTFT :: MTFT -> Seq (Maybe ByteString)
+ Data.MTF: bytestringToBWTToMTFB :: ByteString -> MTFB
+ Data.MTF: bytestringToBWTToMTFT :: ByteString -> MTFT
+ Data.MTF: bytestringToMTFB :: Seq (Maybe ByteString) -> MTFB
+ Data.MTF: bytestringToMTFT :: Seq (Maybe ByteString) -> MTFT
+ Data.MTF: textBWTFromMTFB :: MTFB -> BWT Text
+ Data.MTF: textBWTFromMTFT :: MTFT -> BWT Text
+ Data.MTF: textBWTToMTFB :: TextBWT -> MTFB
+ Data.MTF: textBWTToMTFT :: TextBWT -> MTFT
+ Data.MTF: textFromBWTFromMTFB :: MTFB -> Text
+ Data.MTF: textFromBWTFromMTFT :: MTFT -> Text
+ Data.MTF: textFromMTFB :: MTFB -> Seq (Maybe Text)
+ Data.MTF: textFromMTFT :: MTFT -> Seq (Maybe Text)
+ Data.MTF: textToBWTToMTFB :: Text -> MTFB
+ Data.MTF: textToBWTToMTFT :: Text -> MTFT
+ Data.MTF: textToMTFB :: Seq (Maybe Text) -> MTFB
+ Data.MTF: textToMTFT :: Seq (Maybe Text) -> MTFT
+ Data.MTF.Internal: MTFB :: (Seq Int, Seq (Maybe ByteString)) -> MTFB
+ Data.MTF.Internal: MTFT :: (Seq Int, Seq (Maybe Text)) -> MTFT
+ Data.MTF.Internal: emptyFSTMTFILB :: ST s (FSTMTFILB s a)
+ Data.MTF.Internal: emptyFSTMTFILT :: ST s (FSTMTFILT s a)
+ Data.MTF.Internal: emptyFSTMTFSeqB :: ST s (FSTMTFSeqB s a)
+ Data.MTF.Internal: emptyFSTMTFSeqT :: ST s (FSTMTFSeqT s a)
+ Data.MTF.Internal: emptySTMTFCounterB :: ST s (STMTFCounterB s Int)
+ Data.MTF.Internal: emptySTMTFCounterT :: ST s (STMTFCounterT s Int)
+ Data.MTF.Internal: emptySTMTFILB :: ST s (STMTFILB s a)
+ Data.MTF.Internal: emptySTMTFILT :: ST s (STMTFILT s a)
+ Data.MTF.Internal: emptySTMTFLSSeqB :: ST s (STMTFLSSeqB s a)
+ Data.MTF.Internal: emptySTMTFLSSeqT :: ST s (STMTFLSSeqT s a)
+ Data.MTF.Internal: initializeSTMTFLSSeqB :: STMTFLSSeqB s (Seq Int, Seq (Maybe ByteString)) -> Seq (Maybe ByteString) -> ST s ()
+ Data.MTF.Internal: initializeSTMTFLSSeqT :: STMTFLSSeqT s (Seq Int, Seq (Maybe Text)) -> Seq (Maybe Text) -> ST s ()
+ Data.MTF.Internal: instance GHC.Classes.Eq Data.MTF.Internal.MTFB
+ Data.MTF.Internal: instance GHC.Classes.Eq Data.MTF.Internal.MTFT
+ Data.MTF.Internal: instance GHC.Classes.Ord Data.MTF.Internal.MTFB
+ Data.MTF.Internal: instance GHC.Classes.Ord Data.MTF.Internal.MTFT
+ Data.MTF.Internal: instance GHC.Generics.Generic Data.MTF.Internal.MTFB
+ Data.MTF.Internal: instance GHC.Generics.Generic Data.MTF.Internal.MTFT
+ Data.MTF.Internal: instance GHC.Read.Read Data.MTF.Internal.MTFB
+ Data.MTF.Internal: instance GHC.Read.Read Data.MTF.Internal.MTFT
+ Data.MTF.Internal: instance GHC.Show.Show Data.MTF.Internal.MTFB
+ Data.MTF.Internal: instance GHC.Show.Show Data.MTF.Internal.MTFT
+ Data.MTF.Internal: loadFSTMTFILB :: FSTMTFILB s (Maybe ByteString) -> Seq (Maybe ByteString) -> ST s ()
+ Data.MTF.Internal: loadFSTMTFILT :: FSTMTFILT s (Maybe Text) -> Seq (Maybe Text) -> ST s ()
+ Data.MTF.Internal: loadSTMTFILB :: STMTFILB s (Maybe ByteString) -> Seq (Maybe ByteString) -> ST s ()
+ Data.MTF.Internal: loadSTMTFILT :: STMTFILT s (Maybe Text) -> Seq (Maybe Text) -> ST s ()
+ Data.MTF.Internal: newtype MTFB
+ Data.MTF.Internal: newtype MTFT
+ Data.MTF.Internal: nubSeq' :: Ord a => Seq (Maybe a) -> Seq (Maybe a)
+ Data.MTF.Internal: seqFromMTFB :: MTFB -> ST s FMTFSeqB
+ Data.MTF.Internal: seqFromMTFT :: MTFT -> ST s FMTFSeqT
+ Data.MTF.Internal: seqToMTFB :: PBMTFSeqB -> ST s MTFLSSeqB
+ Data.MTF.Internal: seqToMTFT :: PTMTFSeqT -> ST s MTFLSSeqT
+ Data.MTF.Internal: type FMTFSeqB = Seq (Maybe ByteString)
+ Data.MTF.Internal: type FMTFSeqT = Seq (Maybe Text)
+ Data.MTF.Internal: type FSTMTFILB s a = STRef s (Seq (Maybe ByteString))
+ Data.MTF.Internal: type FSTMTFILT s a = STRef s (Seq (Maybe Text))
+ Data.MTF.Internal: type FSTMTFSeqB s a = STRef s FMTFSeqB
+ Data.MTF.Internal: type FSTMTFSeqT s a = STRef s FMTFSeqT
+ Data.MTF.Internal: type MTFLSSeqB = (Seq Int, Seq (Maybe ByteString))
+ Data.MTF.Internal: type MTFLSSeqT = (Seq Int, Seq (Maybe Text))
+ Data.MTF.Internal: type PBMTFSeqB = Seq (Maybe ByteString)
+ Data.MTF.Internal: type PTMTFSeqT = Seq (Maybe Text)
+ Data.MTF.Internal: type STMTFCounterB s a = STRef s Int
+ Data.MTF.Internal: type STMTFCounterT s a = STRef s Int
+ Data.MTF.Internal: type STMTFILB s a = STRef s (Seq (Maybe ByteString))
+ Data.MTF.Internal: type STMTFILT s a = STRef s (Seq (Maybe Text))
+ Data.MTF.Internal: type STMTFLSSeqB s a = STRef s MTFLSSeqB
+ Data.MTF.Internal: type STMTFLSSeqT s a = STRef s MTFLSSeqT
+ Data.MTF.Internal: updateFSTMTFILB :: FSTMTFILB s (Maybe ByteString) -> Int -> ST s ()
+ Data.MTF.Internal: updateFSTMTFILT :: FSTMTFILT s (Maybe Text) -> Int -> ST s ()
+ Data.MTF.Internal: updateFSTMTFSeqB :: FSTMTFSeqB s (Maybe ByteString) -> Maybe ByteString -> ST s ()
+ Data.MTF.Internal: updateFSTMTFSeqT :: FSTMTFSeqT s (Maybe Text) -> Maybe Text -> ST s ()
+ Data.MTF.Internal: updateSTMTFCounterB :: STMTFCounterB s Int -> Int -> ST s ()
+ Data.MTF.Internal: updateSTMTFCounterT :: STMTFCounterT s Int -> Int -> ST s ()
+ Data.MTF.Internal: updateSTMTFLSSeqB :: STMTFLSSeqB s (Seq Int, Seq (Maybe ByteString)) -> Int -> ST s ()
+ Data.MTF.Internal: updateSTMTFLSSeqT :: STMTFLSSeqT s (Seq Int, Seq (Maybe Text)) -> Int -> ST s ()

Files

CHANGELOG.md view
@@ -39,3 +39,7 @@ ## 0.1.0.9 -- 2022-11-12  * Switching back to sequences for maintainability (for now).++## 0.1.0.10 -- 2022-11-15++* Added Move-to-front transform (MTF) implementation.
src/Data/BWT.hs view
@@ -21,7 +21,17 @@ -- @"Data.BWT.Internal"@ also has the function 'createBWTMatrix', which can be useful as well, although not used by either 'toBWT' or 'fromBWT'.  -module Data.BWT where+module Data.BWT ( -- * To BWT functions+                  toBWT,+                  bytestringToBWT,+                  TextBWT(..),+                  textToBWT,+                  -- * From BWT functions+                  fromBWT,+                  bytestringFromWord8BWT,+                  bytestringFromByteStringBWT,+                  textFromBWT+                ) where  import Data.BWT.Internal @@ -42,9 +52,9 @@  -- | Takes a String and returns the Burrows-Wheeler Transform (BWT). -- Implemented via a 'SuffixArray'.-toBWT :: Ord a =>-         [a]   ->-         BWT a+toBWT :: Ord a+      => [a]+      -> BWT a toBWT [] = BWT DS.Empty toBWT xs = do   let saxs = createSuffixArray xss@@ -55,8 +65,8 @@  -- | Helper function for converting a 'ByteString' -- to a 'BWT' 'Word8'.-bytestringToBWT :: ByteString ->-                   BWT Word8+bytestringToBWT :: ByteString+                -> BWT Word8 bytestringToBWT = toBWT . BS.unpack  -- | A newtype to ensure you only uncompress a BWT created@@ -66,8 +76,8 @@  -- | Helper function for converting 'Text' -- to a 'TextBWT'.-textToBWT :: Text ->-             TextBWT+textToBWT :: Text+          -> TextBWT textToBWT = TextBWT . bytestringToBWT . DTE.encodeUtf8  {-------------------}@@ -80,9 +90,9 @@ -- This function utilizes the state monad (strict) in order -- to implement the [Magic](https://www.youtube.com/watch?v=QwSsppKrCj4) Inverse BWT algorithm by backtracking -- indices starting with the (__Nothing__,_) entry.-fromBWT :: Ord a =>-           BWT a ->-           [a]+fromBWT :: Ord a+        => BWT a+        -> [a] fromBWT bwt = do   let originall = CMST.runST $ magicInverseBWT magicsz   DFold.toList originall@@ -107,7 +117,8 @@  -- | Helper function for converting 'TextBWT' -- to a 'Text'-textFromBWT :: TextBWT -> Text+textFromBWT :: TextBWT+            -> Text textFromBWT (TextBWT x) = DTE.decodeUtf8 $                           bytestringFromWord8BWT x 
src/Data/BWT/Internal.hs view
@@ -33,7 +33,7 @@ -- Various data structures and custom data types to describe the Burrows-Wheeler Transform (BWT) -- and the Inverse BWT. ----- The implementation of the BWT relies upon sequence provided+-- The implementation of the BWT relies upon 'DS.Seq' provided -- by the [containers](https://hackage.haskell.org/package/containers). -- -- The internal 'BWTMatrix' data type relies upon the [massiv](https://hackage.haskell.org/package/massiv) package.@@ -66,11 +66,11 @@   deriving (Show,Read,Eq,Ord,Generic)  -- | The SuffixArray data type.--- Uses sequence internally.+-- Uses 'DS.Seq' internally. type SuffixArray a = Seq (Suffix a)  -- | The BWT data type.--- Uses sequence internally.+-- Uses 'DS.Seq' internally. newtype BWT a = BWT (Seq (Maybe a))   deriving (Eq,Ord,Show,Read,Generic) @@ -85,10 +85,10 @@ {-toBWT functions.-}  -- | Computes the Burrows-Wheeler Transform (BWT) using the suffix array--- and the original string (represented as a sequence for performance).-saToBWT :: SuffixArray a ->-           Seq a         ->-           Seq (Maybe a)+-- and the original string (represented as a 'DS.Seq' for performance).+saToBWT :: SuffixArray a+        -> Seq a        +        -> Seq (Maybe a) saToBWT DS.Empty      _ = DS.Empty saToBWT (y DS.:<| ys) t =   if | suffixstartpos y /= 1@@ -100,9 +100,9 @@  -- | Computes the corresponding 'SuffixArray' of a given string. Please see [suffix array](https://en.wikipedia.org/wiki/Suffix_array) -- for more information. -createSuffixArray :: Ord a =>-                     Seq a ->-                     SuffixArray a+createSuffixArray :: Ord a+                  => Seq a+                  -> SuffixArray a createSuffixArray xs =   fmap (\(a,b,c) -> if | not $ DS.null c                        -> Suffix { suffixindex    = a@@ -134,21 +134,23 @@ -- | Hierarchical sorting scheme that compares fst first then snd. -- Necessary for the setting up the BWT in order to correctly -- invert it using the [Magic](https://www.youtube.com/watch?v=QwSsppKrCj4) algorithm.-sortTB :: (Ord a1, Ord a2) =>-          (a1, a2)         ->-          (a1, a2)         ->-          Ordering+sortTB :: (Ord a1,Ord a2)+       => (a1, a2)+       -> (a1, a2)+       -> Ordering sortTB (c1,i1) (c2,i2) = compare c1 c2 <>                          compare i1 i2 --- | Abstract BWTSeq type utilizing a sequence.+-- | Abstract BWTSeq type utilizing a 'DS.Seq'. type BWTSeq a = Seq a  -- | Abstract data type representing a BWTSeq in the (strict) ST monad. type STBWTSeq s a = STRef s (BWTSeq a)  -- | State function to push BWTString data into stack.-pushSTBWTSeq :: STBWTSeq s a -> a -> ST s ()+pushSTBWTSeq :: STBWTSeq s a+             -> a+             -> ST s () pushSTBWTSeq s e = do   s2 <- readSTRef s   writeSTRef s (s2 DS.|> e)@@ -161,7 +163,9 @@ type STBWTCounter s a = STRef s Int  -- | State function to update BWTCounter.-updateSTBWTCounter :: STBWTCounter s Int -> Int -> ST s ()+updateSTBWTCounter :: STBWTCounter s Int+                   -> Int+                   -> ST s () updateSTBWTCounter s e = writeSTRef s e  -- | State function to create empty STBWTCounter type.@@ -169,8 +173,8 @@ emptySTBWTCounter = newSTRef (-1)  -- | "Magic" Inverse BWT function.-magicInverseBWT :: Seq (Maybe a,Int) ->-                   ST s (BWTSeq a)+magicInverseBWT :: Seq (Maybe a,Int)+                -> ST s (BWTSeq a) magicInverseBWT DS.Empty = do   bwtseqstackempty  <- emptySTBWTSeq   bwtseqstackemptyr <- readSTRef bwtseqstackempty@@ -211,8 +215,8 @@  -- | Simple yet efficient implementation of converting a given string -- into a BWT Matrix (the BWTMatrix type is a massiv array).-createBWTMatrix :: String ->-                   BWTMatrix+createBWTMatrix :: String+                -> BWTMatrix createBWTMatrix t =   DMA.fromList (ParN 0) zippedffff :: Array BN Ix1 String     where
+ src/Data/MTF.hs view
@@ -0,0 +1,344 @@+{-# LANGUAGE MultiWayIf        #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns      #-}+{-# LANGUAGE Strict            #-}+++-- |+-- Module      :  Data.MTF+-- Copyright   :  (c) Matthew Mosior 2022+-- License     :  BSD-style+-- Maintainer  :  mattm.github@gmail.com+-- Portability :  portable+--+-- = Move-to-front transform (MTF)+++module Data.MTF ( -- * To MTF functions+                  bytestringToBWTToMTFB,+                  bytestringToBWTToMTFT,+                  textToBWTToMTFB,+                  textToBWTToMTFT,+                  textBWTToMTFB,+                  bytestringBWTToMTFB,+                  textBWTToMTFT,+                  bytestringBWTToMTFT,+                  textToMTFB,+                  bytestringToMTFB,+                  textToMTFT,+                  bytestringToMTFT,+                  -- * From MTF functions+                  bytestringFromBWTFromMTFB,+                  bytestringFromBWTFromMTFT,+                  textFromBWTFromMTFB,+                  textFromBWTFromMTFT,+                  textBWTFromMTFT,+                  bytestringBWTFromMTFT,+                  textBWTFromMTFB,+                  bytestringBWTFromMTFB,+                  textFromMTFB,+                  bytestringFromMTFB,+                  textFromMTFT,+                  bytestringFromMTFT+                ) where++import Data.BWT+import Data.BWT.Internal +import Data.MTF.Internal++import Control.Monad()+import Control.Monad.ST as CMST+import Control.Monad.State.Strict()+import Data.ByteString as BS+import Data.ByteString.Char8()+import Data.Char()+import Data.Foldable()+import Data.Maybe as DMaybe (isNothing,fromJust)+import Data.Sequence as DS (Seq(..))+import Data.STRef()+import Data.Text as DText +import Data.Text.Encoding as DTE (decodeUtf8,encodeUtf8)+import Data.Word (Word8)+import Prelude as P+++{-toMTF Function(s)-}++-- | Helper function for converting a 'ByteString'+-- to a 'MTFB' via a 'BWT' first.+bytestringToBWTToMTFB :: ByteString ->+                         MTFB+bytestringToBWTToMTFB = bytestringBWTToMTFB . bytestringToBWT++-- | Helper function for converting a 'ByteString'+-- to a 'MTFT' via a 'BWT' first.+bytestringToBWTToMTFT :: ByteString ->+                         MTFT+bytestringToBWTToMTFT = bytestringBWTToMTFT . bytestringToBWT++-- | Helper function for converting a 'Text'+-- to a 'MTFB' via a 'BWT' first.+textToBWTToMTFB :: Text ->+                   MTFB+textToBWTToMTFB = textBWTToMTFB . textToBWT++-- | Helper function for converting a 'Text'+-- to a 'MTFT' via a 'BWT' first.+textToBWTToMTFT :: Text ->+                   MTFT+textToBWTToMTFT = textBWTToMTFT . textToBWT++-- | Take a 'BWT' of 'Word8's and generate the+-- Move-to-front transform ('MTFB').+textBWTToMTFB :: TextBWT+              -> MTFB+textBWTToMTFB xs =+  MTFB (CMST.runST $ seqToMTFB xss)+    where+      xss = fmap (\x -> if | isNothing x+                           -> Nothing+                           | otherwise+                           -> Just         $+                              BS.singleton $+                              fromJust x+                 )+            ((\(BWT t) -> t) $+            ((\(TextBWT t) -> t) xs))++-- | Take a 'BWT' of 'Word8's and generate the+-- Move-to-front transform ('MTFB').+bytestringBWTToMTFB :: BWT Word8+                    -> MTFB+bytestringBWTToMTFB xs =+  MTFB (CMST.runST $ seqToMTFB xss)+    where+      xss = fmap (\x -> if | isNothing x+                           -> Nothing+                           | otherwise+                           -> Just         $+                              BS.singleton $+                              fromJust x+                 )+            ((\(BWT t) -> t) xs)++-- | Take a 'BWT' of 'Word8's and generate the+-- Move-to-front transform ('MTFB').+textBWTToMTFT :: TextBWT+              -> MTFT+textBWTToMTFT xs =+  MTFT (CMST.runST $ seqToMTFT xss)+    where+      xss = fmap (\x -> if | isNothing x+                           -> Nothing+                           | otherwise+                           -> Just           $+                              DTE.decodeUtf8 $+                              BS.singleton   $+                              fromJust x+                 )+            ((\(BWT t) -> t) $+            ((\(TextBWT t) -> t) xs))++-- | Take a 'BWT' of 'Word8's and generate the+-- Move-to-front transform ('MTFT').+bytestringBWTToMTFT :: BWT Word8+                    -> MTFT+bytestringBWTToMTFT xs =+  MTFT (CMST.runST $ seqToMTFT xss)+    where+      xss = fmap (\x -> if | isNothing x+                           -> Nothing+                           | otherwise+                           -> Just           $+                              DTE.decodeUtf8 $+                              BS.singleton   $+                              fromJust x+                 )+            ((\(BWT t) -> t) xs)++-- | Takes a 'Text' and returns the Move-to-front transform ('MTFB').+textToMTFB :: Seq (Maybe Text)+           -> MTFB+textToMTFB DS.Empty = MTFB (DS.Empty,DS.Empty)+textToMTFB xs       = +  MTFB (CMST.runST $ seqToMTFB xss)+    where+      xss = fmap (\x -> if | isNothing x+                           -> Nothing+                           | otherwise+                           -> Just            $+                               DTE.encodeUtf8 $+                               fromJust x+                 )+            xs++-- | Takes a 'Seq' of 'ByteString's and returns the Move-to-front transform ('MTFB').+bytestringToMTFB :: Seq (Maybe ByteString)+                 -> MTFB+bytestringToMTFB DS.Empty = MTFB (DS.Empty,DS.Empty)+bytestringToMTFB xs       =+ MTFB (CMST.runST $ seqToMTFB xs)++-- | Takes a 'Text' and returns the Move-to-front transform ('MTFT').+textToMTFT :: Seq (Maybe Text)+           -> MTFT+textToMTFT DS.Empty = MTFT (DS.Empty,DS.Empty)+textToMTFT xs       =+  MTFT (CMST.runST $ seqToMTFT xs)++-- | Takes a 'ByteString' and returns the Move-to-front transform ('MTFT').+bytestringToMTFT :: Seq (Maybe ByteString)+                 -> MTFT+bytestringToMTFT DS.Empty = MTFT (DS.Empty,DS.Empty)+bytestringToMTFT xs       =+  MTFT (CMST.runST $ seqToMTFT xss)+    where+      xss = fmap (\x -> if | isNothing x+                           -> Nothing+                           | otherwise+                           -> Just           $+                              DTE.decodeUtf8 $+                              fromJust x+                 )+            xs ++{-------------------}+++{-fromMTF function(s)-}++-- | Helper function for converting a 'BWT'ed 'MTFB'+-- back to the original 'ByteString'.+bytestringFromBWTFromMTFB :: MTFB +                          -> ByteString+bytestringFromBWTFromMTFB = bytestringFromByteStringBWT . bytestringBWTFromMTFB++-- | Helper function for converting a 'BWT'ed 'MTFT'+-- back to the original 'ByteString'.+bytestringFromBWTFromMTFT :: MTFT+                          -> ByteString+bytestringFromBWTFromMTFT xs = bytestringFromByteStringBWT $+                               BWT                         $+                               fmap (\x -> if | isNothing x+                                              -> Nothing+                                              | otherwise+                                              -> Just           $+                                                 DTE.encodeUtf8 $+                                                 fromJust x+                                    )+                                                           $+                            ((\(BWT t) -> t) (textBWTFromMTFT xs))++-- | Helper function for converting a 'BWT'ed 'MTFB'+-- back to the original 'Text'.+textFromBWTFromMTFB :: MTFB+                    -> Text+textFromBWTFromMTFB = DTE.decodeUtf8 . bytestringFromByteStringBWT . bytestringBWTFromMTFB++-- | Helper function for converting a 'BWT'ed 'MTFT'+-- back to the original 'Text'.+textFromBWTFromMTFT :: MTFT+                    -> Text+textFromBWTFromMTFT = DTE.decodeUtf8 . bytestringFromByteStringBWT . bytestringBWTFromMTFT++-- | Takes a 'MTFT' and returns+-- the 'BWT' of 'Text's.+textBWTFromMTFT :: MTFT+                -> BWT Text+textBWTFromMTFT (MTFT (DS.Empty,_)) = BWT DS.Empty+textBWTFromMTFT (MTFT (_,DS.Empty)) = BWT DS.Empty+textBWTFromMTFT xs                  = +  BWT (CMST.runST $ seqFromMTFT xs)++-- | Takes a 'MTFT' and returns+-- the 'BWT' of 'ByteString's.+bytestringBWTFromMTFT :: MTFT+                      -> BWT ByteString+bytestringBWTFromMTFT (MTFT (DS.Empty,_)) = BWT DS.Empty+bytestringBWTFromMTFT (MTFT (_,DS.Empty)) = BWT DS.Empty+bytestringBWTFromMTFT xs                  = do+  let originalbwtb = CMST.runST $ seqFromMTFT xs+  BWT (fmap (\x -> if | isNothing x+                      -> Nothing+                      | otherwise+                      -> Just           $+                         DTE.encodeUtf8 $+                        fromJust x +            ) originalbwtb)++-- | Takes a 'MTFB' and returns+-- the 'BWT' of 'Text's.+textBWTFromMTFB :: MTFB+                -> BWT Text+textBWTFromMTFB (MTFB (DS.Empty,_)) = BWT DS.Empty+textBWTFromMTFB (MTFB (_,DS.Empty)) = BWT DS.Empty+textBWTFromMTFB xs                  = do+  let originalbwtt = CMST.runST $ seqFromMTFB xs+  BWT (fmap (\x -> if | isNothing x+                      -> Nothing+                      | otherwise+                      -> Just           $+                         DTE.decodeUtf8 $+                        fromJust x+            ) originalbwtt)++-- | Take a 'MTFB' and returns+-- the 'BWT' of 'ByteString's.+bytestringBWTFromMTFB :: MTFB +                      -> BWT ByteString+bytestringBWTFromMTFB (MTFB (DS.Empty,_)) = BWT DS.Empty+bytestringBWTFromMTFB (MTFB (_,DS.Empty)) = BWT DS.Empty+bytestringBWTFromMTFB xs              =+  BWT (CMST.runST $ seqFromMTFB xs)++-- | Takes a 'MTFB' and returns+-- the original 'Seq' of 'Text's.+textFromMTFB :: MTFB+             -> Seq (Maybe Text)+textFromMTFB (MTFB (DS.Empty,_)) = DS.Empty+textFromMTFB (MTFB (_,DS.Empty)) = DS.Empty+textFromMTFB xs                  = do+  let originalt = CMST.runST $ seqFromMTFB xs+  fmap (\x -> if | isNothing x+                 -> Nothing+                 | otherwise+                 -> Just           $+                    DTE.decodeUtf8 $+                    fromJust x+       ) originalt++-- | Takes a 'MTFB' and returns+-- the original 'Seq' of 'ByteString's.+bytestringFromMTFB :: MTFB+                   -> Seq (Maybe ByteString)+bytestringFromMTFB (MTFB (DS.Empty,_)) = DS.Empty+bytestringFromMTFB (MTFB (_,DS.Empty)) = DS.Empty+bytestringFromMTFB xs                  =+  CMST.runST $ seqFromMTFB xs++-- | Takes a 'MTFT' and returns+-- the original 'Seq' of 'Text's.+textFromMTFT :: MTFT+             -> Seq (Maybe Text)+textFromMTFT (MTFT (DS.Empty,_)) = DS.Empty+textFromMTFT (MTFT (_,DS.Empty)) = DS.Empty+textFromMTFT xs                  =+  CMST.runST $ seqFromMTFT xs++-- | Takes a 'MTFT' and returns+-- the original 'Seq' of 'ByteString's.+bytestringFromMTFT :: MTFT+                   -> Seq (Maybe ByteString)+bytestringFromMTFT (MTFT (DS.Empty,_)) = DS.Empty+bytestringFromMTFT (MTFT (_,DS.Empty)) = DS.Empty+bytestringFromMTFT xs                  = do+  let originalb = CMST.runST $ seqFromMTFT xs+  fmap (\x -> if | isNothing x+                 -> Nothing+                 | otherwise+                 -> Just           $ +                    DTE.encodeUtf8 $+                    fromJust x+       ) originalb++{---------------------}
+ src/Data/MTF/Internal.hs view
@@ -0,0 +1,518 @@+{-# LANGUAGE MultiWayIf       #-}+{-# LANGUAGE ViewPatterns     #-}+{-# LANGUAGE Strict           #-}+{-# LANGUAGE DeriveGeneric    #-}+{-# LANGUAGE TypeApplications #-}+++-- |+-- Module      :  Data.MTF.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 Move-to-front transform (MTF)+-- and the Inverse MTF implementations, namely 'seqToMTFB', 'seqToMTFT', 'seqFromMTFB', and 'seqFromMTFT'.+--+-- The MTF 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.MTF.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()+import Data.ByteString.Internal()+import Data.Foldable as DFold (foldr')+import Data.List()+import Data.Maybe()+import Data.Set as DSet+import Data.Sequence as DS (Seq(..),deleteAt,findIndexL,empty,index,unstableSort,(|>),(<|))+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 MTF ('ByteString') data type.+newtype MTFB = MTFB ((Seq Int,Seq (Maybe ByteString)))+  deriving (Eq,Ord,Show,Read,Generic)++-- | Basic MTF ('Text') data type.+newtype MTFT = MTFT ((Seq Int,Seq (Maybe Text)))+  deriving (Eq,Ord,Show,Read,Generic)++{-------------------}+++{-Auxilary function(s).-}++-- | Useful to acquire the unique elements+-- that make up a 'Seq'.+-- Credit to @DavidFletcher.+-- See [this stackoverflow post](https://stackoverflow.com/questions/45757839/removing-duplicate-elements-in-a-seq).+nubSeq' :: Ord a+        => Seq (Maybe a)+        -> Seq (Maybe a)+nubSeq' xs =+  unstableSort $+  DFold.foldr' cons'+               nil+               xs+               DSet.empty+    where+      cons' :: Ord a+           => Maybe a+           -> (Set (Maybe a) -> Seq (Maybe a))+           -> (Set (Maybe a) -> Seq (Maybe a))+      cons' y ys seen = if | y `P.elem` seen+                           -> ys seen+                           | otherwise+                           -> y DS.<| ys (DSet.insert y seen)+      nil :: Set (Maybe a)+          -> Seq (Maybe a)+      nil _ = DS.empty++{-----------------------}+++{-toMTF (ByteString) functions.-}++-- | Abstract 'PBMTFSeqB' type utilizing a 'Seq'+type PBMTFSeqB = Seq (Maybe ByteString)++-- | Abstract 'MTFLSSeqB' type utilizing a 'Seq'.+type MTFLSSeqB = (Seq Int,Seq (Maybe ByteString))++-- | Abstract data type representing a 'MTFLSSeqB' in the (strict) ST monad.+type STMTFLSSeqB s a = STRef s MTFLSSeqB++-- | Abstract data type to initialize a 'STMTFLSSeqB'+-- using the initial list.+initializeSTMTFLSSeqB :: STMTFLSSeqB s (Seq Int,Seq (Maybe ByteString))+                     -> Seq (Maybe ByteString)+                     -> ST s ()+initializeSTMTFLSSeqB s DS.Empty = do+  (s2i,_) <- readSTRef s+  writeSTRef s (s2i,DS.empty)+initializeSTMTFLSSeqB s e        = do+  (s2i,_) <- readSTRef s+  writeSTRef s (s2i,e)++-- | State function to update 'MTFLSSeqB'+-- with each step of the MTF.+updateSTMTFLSSeqB :: STMTFLSSeqB s (Seq Int,Seq (Maybe ByteString))+                  -> Int+                  -> ST s () +updateSTMTFLSSeqB s i = do+  (s2i,s2b) <- readSTRef s+  let newheade = DS.index s2b i+  writeSTRef s (s2i,DS.deleteAt i s2b)+  (ns2i,ns2b) <- readSTRef s+  writeSTRef s (ns2i DS.|> i,newheade DS.<| ns2b)++-- | State function to create empty 'STMTFLSSeqB' type.+emptySTMTFLSSeqB :: ST s (STMTFLSSeqB s a)+emptySTMTFLSSeqB = newSTRef (DS.empty,DS.empty) ++-- | Abstract 'STMTFILB' and associated state type.+type STMTFILB s a = STRef s (Seq (Maybe ByteString))++-- | State function to load list into 'STMTFILB'.+loadSTMTFILB :: STMTFILB s (Maybe ByteString)+             -> Seq (Maybe ByteString)+             -> ST s ()+loadSTMTFILB s e = writeSTRef s e++-- | State function to create empty 'STMTFILB' type.+emptySTMTFILB :: ST s (STMTFILB s a)+emptySTMTFILB = newSTRef DS.empty++-- | Abstract 'STMTFCounterB' and associated state type.+type STMTFCounterB s a = STRef s Int++-- | State function to update 'STMTFCounterB'.+updateSTMTFCounterB :: STMTFCounterB s Int+                    -> Int+                    -> ST s ()+updateSTMTFCounterB s e = writeSTRef s e++-- | State function to create empty 'STMTFCounterB' type.+emptySTMTFCounterB :: ST s (STMTFCounterB s Int)+emptySTMTFCounterB = newSTRef (-1)++-- | Strict state monad function.+seqToMTFB :: PBMTFSeqB+          -> ST s MTFLSSeqB+seqToMTFB DS.Empty      = do+  bmtfseqstackempty  <- emptySTMTFLSSeqB+  bmtfseqstackemptyr <- readSTRef bmtfseqstackempty+  return bmtfseqstackemptyr+seqToMTFB xs            = do+  bmtfseqstack     <- emptySTMTFLSSeqB+  bmtfinitiallist  <- emptySTMTFILB+  bmtfcounterstack <- emptySTMTFCounterB+  let il = nubSeq' xs+  loadSTMTFILB bmtfinitiallist+               il +  iMTFB xs+        bmtfinitiallist+        bmtfseqstack+        bmtfcounterstack +  bmtfseqstackr <- readSTRef bmtfseqstack+  return bmtfseqstackr+    where+      iMTFB DS.Empty      _      _      _      = pure ()+      iMTFB (y DS.:<| ys) bmtfil bmtfss bmtfcs = do+        cbmtfcs <- readSTRef bmtfcs+        if | cbmtfcs == (-1)+           -> do updateSTMTFCounterB bmtfcs+                                     1+                 cbmtfil <- readSTRef bmtfil+                 initializeSTMTFLSSeqB bmtfss+                                       cbmtfil+                 (_,cbmtfss) <- readSTRef bmtfss+                 case (DS.findIndexL (\z -> z == y) cbmtfss) of+                   Nothing     -> iMTFB ys+                                        bmtfil+                                        bmtfss+                                        bmtfcs+                   Just bindex -> do updateSTMTFLSSeqB bmtfss+                                                       bindex+                                     iMTFB ys+                                           bmtfil+                                           bmtfss+                                           bmtfcs+           | otherwise+           -> do (_,cbmtfss) <- readSTRef bmtfss+                 case (DS.findIndexL (\z -> z == y) cbmtfss) of+                   Nothing     -> iMTFB ys+                                        bmtfil+                                        bmtfss+                                        bmtfcs+                   Just bindex -> do updateSTMTFLSSeqB bmtfss+                                                       bindex+                                     iMTFB ys+                                           bmtfil+                                           bmtfss+                                           bmtfcs++{-------------------------------}+++{-toMTF (Text) functions.-}++-- | Abstract 'PTMTFSeqT' type utilizing a 'Seq'+type PTMTFSeqT = Seq (Maybe Text)++-- | Abstract 'MTFLSSeqT' type utilizing a 'Seq'.+type MTFLSSeqT = (Seq Int,Seq (Maybe Text))++-- | Abstract data type representing a 'MTFLSSeqT' in the (strict) ST monad.+type STMTFLSSeqT s a = STRef s MTFLSSeqT++-- | Abstract data type to initialize a 'STMTFLSSeqT'+-- using the initial list.+initializeSTMTFLSSeqT :: STMTFLSSeqT s (Seq Int,Seq (Maybe Text))+                      -> Seq (Maybe Text)+                      -> ST s ()+initializeSTMTFLSSeqT s DS.Empty  = do+  (s2i,_) <- readSTRef s+  writeSTRef s (s2i,DS.empty)+initializeSTMTFLSSeqT s e         = do+  (s2i,_) <- readSTRef s+  writeSTRef s (s2i,e)++-- | State function to update 'STMTFLSSeqT'+-- with each step of the MTF.+updateSTMTFLSSeqT :: STMTFLSSeqT s (Seq Int,Seq (Maybe Text))+                  -> Int+                  -> ST s ()+updateSTMTFLSSeqT s i = do+  (s2i,s2b) <- readSTRef s+  let newheade = DS.index s2b i+  writeSTRef s (s2i,DS.deleteAt i s2b)+  (ns2i,ns2b) <- readSTRef s+  writeSTRef s (ns2i DS.|> i,newheade DS.<| ns2b)++-- | State function to create empty 'STMTFLSSeqT' type.+emptySTMTFLSSeqT :: ST s (STMTFLSSeqT s a)+emptySTMTFLSSeqT = newSTRef (DS.empty,DS.empty)++-- | Abstract 'STMTFILT' and associated state type.+type STMTFILT s a = STRef s (Seq (Maybe Text))++-- | State function to load list into 'STMTFILT'.+loadSTMTFILT :: STMTFILT s (Maybe Text)+             -> Seq (Maybe Text)+             -> ST s ()+loadSTMTFILT s e = writeSTRef s e++-- | State function to create empty 'STMTFILT' type.+emptySTMTFILT :: ST s (STMTFILT s a)+emptySTMTFILT = newSTRef DS.empty++-- | Abstract 'STMTFCounterT' and associated state type.+type STMTFCounterT s a = STRef s Int++-- | State function to update 'STMTFCounterT'.+updateSTMTFCounterT :: STMTFCounterT s Int+                    -> Int+                    -> ST s ()+updateSTMTFCounterT s e = writeSTRef s e++-- | State function to create empty 'STMTFCounterT' type.+emptySTMTFCounterT :: ST s (STMTFCounterT s Int)+emptySTMTFCounterT = newSTRef (-1)++-- | Strict state monad function.+seqToMTFT :: PTMTFSeqT+          -> ST s MTFLSSeqT+seqToMTFT DS.Empty      = do+  tmtfseqstackempty  <- emptySTMTFLSSeqT+  tmtfseqstackemptyr <- readSTRef tmtfseqstackempty+  return tmtfseqstackemptyr+seqToMTFT xs            = do+  tmtfseqstack     <- emptySTMTFLSSeqT+  tmtfinitiallist  <- emptySTMTFILT+  tmtfcounterstack <- emptySTMTFCounterT+  let il = nubSeq' xs+  loadSTMTFILT tmtfinitiallist+               il+  iMTFT xs+        tmtfinitiallist+        tmtfseqstack+        tmtfcounterstack+  tmtfseqstackr <- readSTRef tmtfseqstack+  return tmtfseqstackr+    where+      iMTFT DS.Empty      _      _      _      = pure ()+      iMTFT (y DS.:<| ys) tmtfil tmtfss tmtfcs = do+        ctmtfcs <- readSTRef tmtfcs+        if | ctmtfcs == (-1)+           -> do updateSTMTFCounterT tmtfcs+                                     1+                 ctmtfil <- readSTRef tmtfil+                 initializeSTMTFLSSeqT tmtfss+                                       ctmtfil+                 (_,ctmtfss) <- readSTRef tmtfss+                 case (DS.findIndexL (\z -> z == y) ctmtfss) of+                   Nothing     -> iMTFT ys+                                        tmtfil+                                        tmtfss+                                        tmtfcs+                   Just tindex -> do updateSTMTFLSSeqT tmtfss+                                                       tindex+                                     iMTFT ys+                                           tmtfil+                                           tmtfss+                                           tmtfcs+           | otherwise+           -> do (_,ctmtfss) <- readSTRef tmtfss+                 case (DS.findIndexL (\z -> z == y) ctmtfss) of+                   Nothing     -> iMTFT ys+                                        tmtfil+                                        tmtfss+                                        tmtfcs+                   Just tindex -> do updateSTMTFLSSeqT tmtfss+                                                       tindex+                                     iMTFT ys+                                           tmtfil+                                           tmtfss+                                           tmtfcs++{-------------------------}+++{-fromMTF (ByteString) functions.-}++-- | Abstract 'FMTFSeqB' type utilizing a 'Seq'.+type FMTFSeqB = Seq (Maybe ByteString)++-- | Abstract data type representing a 'FMTFSeqB' in the (strict) ST monad.+type FSTMTFSeqB s a = STRef s FMTFSeqB++-- | State function to update 'FSTMTFSeqB' with each step of the inverse MTF.+updateFSTMTFSeqB :: FSTMTFSeqB s (Maybe ByteString)+                 -> (Maybe ByteString)+                 -> ST s ()+updateFSTMTFSeqB s Nothing  = do+  s2 <- readSTRef s+  writeSTRef s (s2 DS.|> Nothing)+updateFSTMTFSeqB s (Just e) = do+  s2 <- readSTRef s+  writeSTRef s (s2 DS.|> (Just e))++-- | State function to create empty 'FSTMTFSeqB' type.+emptyFSTMTFSeqB :: ST s (FSTMTFSeqB s a)+emptyFSTMTFSeqB = newSTRef DS.empty++-- | Abstract 'FSTMTFILB' and associated state type.+type FSTMTFILB s a = STRef s (Seq (Maybe ByteString))++-- | State function to load list into 'FSTMTFILB'.+loadFSTMTFILB :: FSTMTFILB s (Maybe ByteString) -> Seq (Maybe ByteString) -> ST s ()+loadFSTMTFILB s e = writeSTRef s e++-- | State function to update 'FSTMTFILB'.+updateFSTMTFILB :: FSTMTFILB s (Maybe ByteString)+                -> Int+                -> ST s ()+updateFSTMTFILB s i = do+  s2 <- readSTRef s+  let newheade = DS.index s2 i+  writeSTRef s (DS.deleteAt i s2)+  ns2 <- readSTRef s +  writeSTRef s (newheade DS.<| ns2)++-- | State function to create empty 'FSTMTFILB' type.+emptyFSTMTFILB :: ST s (FSTMTFILB s a)+emptyFSTMTFILB = newSTRef DS.empty++-- | Strict state monad function.+seqFromMTFB :: MTFB+            -> ST s FMTFSeqB+seqFromMTFB (MTFB (DS.Empty,_)) = do+  fbmtfseqstackempty  <- emptyFSTMTFSeqB+  fbmtfseqstackemptyr <- readSTRef fbmtfseqstackempty+  return fbmtfseqstackemptyr+seqFromMTFB (MTFB (_,DS.Empty)) = do+  fbmtfseqstackempty  <- emptyFSTMTFSeqB+  fbmtfseqstackemptyr <- readSTRef fbmtfseqstackempty+  return fbmtfseqstackemptyr+seqFromMTFB xs                  = do+  let xss = (\(MTFB b) -> b) xs+  fbmtfseqstack     <- emptyFSTMTFSeqB +  fbmtfinitiallist  <- emptyFSTMTFILB+  let il = nubSeq' (snd xss)+  loadFSTMTFILB fbmtfinitiallist+                il+  iFMTFB (fst xss)+         fbmtfinitiallist+         fbmtfseqstack+  fbmtfseqstackr <- readSTRef fbmtfseqstack+  return fbmtfseqstackr+    where+      iFMTFB DS.Empty      _       _       = pure ()+      iFMTFB (y DS.:<| ys) fbmtfil fbmtfss = do+        cfbmtfil <- readSTRef fbmtfil+        updateFSTMTFSeqB fbmtfss+                         (DS.index cfbmtfil y)+        updateFSTMTFILB fbmtfil+                        y +        iFMTFB ys+               fbmtfil+               fbmtfss++{---------------------------------}+++{-fromRLE (Text) functions.-}++-- | Abstract 'FMTFSeqT' type utilizing a 'Seq'.+type FMTFSeqT = Seq (Maybe Text)++-- | Abstract data type representing a 'FMTFSeqT' in the (strict) ST monad.+type FSTMTFSeqT s a = STRef s FMTFSeqT++-- | State function to update 'FSTMTFSeqT' with each step of the inverse MTF.+updateFSTMTFSeqT :: FSTMTFSeqT s (Maybe Text)+                 -> (Maybe Text)+                 -> ST s ()+updateFSTMTFSeqT s Nothing  = do+  s2 <- readSTRef s+  writeSTRef s (s2 DS.|> Nothing)+updateFSTMTFSeqT s (Just e) = do+  s2 <- readSTRef s+  writeSTRef s (s2 DS.|> (Just e))++-- | State function to create empty 'FSTMTFSeqT' type.+emptyFSTMTFSeqT :: ST s (FSTMTFSeqT s a)+emptyFSTMTFSeqT = newSTRef DS.empty++-- | Abstract 'FSTMTFILT' and associated state type.+type FSTMTFILT s a = STRef s (Seq (Maybe Text))++-- | State function to load list into 'FSTMTFILT'.+loadFSTMTFILT :: FSTMTFILT s (Maybe Text)+              -> Seq (Maybe Text)+              -> ST s ()+loadFSTMTFILT s e = writeSTRef s e++-- | State function to update 'FSTMTFILT'.+updateFSTMTFILT :: FSTMTFILT s (Maybe Text)+                -> Int+                -> ST s ()+updateFSTMTFILT s i = do+  s2 <- readSTRef s+  let newheade = DS.index s2 i+  writeSTRef s (DS.deleteAt i s2)+  ns2 <- readSTRef s+  writeSTRef s (newheade DS.<| ns2)++-- | State function to create empty 'FSTMTFILT' type.+emptyFSTMTFILT :: ST s (FSTMTFILT s a)+emptyFSTMTFILT = newSTRef DS.empty++-- | Strict state monad function.+seqFromMTFT :: MTFT+            -> ST s FMTFSeqT+seqFromMTFT (MTFT (DS.Empty,_)) = do+  ftmtfseqstackempty  <- emptyFSTMTFSeqT+  ftmtfseqstackemptyr <- readSTRef ftmtfseqstackempty+  return ftmtfseqstackemptyr+seqFromMTFT (MTFT (_,DS.Empty)) = do+  ftmtfseqstackempty  <- emptyFSTMTFSeqT+  ftmtfseqstackemptyr <- readSTRef ftmtfseqstackempty+  return ftmtfseqstackemptyr+seqFromMTFT xs                  = do+  let xss = (\(MTFT t) -> t) xs+  ftmtfseqstack     <- emptyFSTMTFSeqT+  ftmtfinitiallist  <- emptyFSTMTFILT+  let il = nubSeq' (snd xss)+  loadFSTMTFILT ftmtfinitiallist+                il+  iFMTFT (fst xss)+         ftmtfinitiallist+         ftmtfseqstack+  ftmtfseqstackr <- readSTRef ftmtfseqstack+  return ftmtfseqstackr+    where+      iFMTFT DS.Empty      _       _       = pure ()+      iFMTFT (y DS.:<| ys) ftmtfil ftmtfss = do+        cftmtfil <- readSTRef ftmtfil+        updateFSTMTFSeqT ftmtfss+                         (DS.index cftmtfil y)+        updateFSTMTFILT ftmtfil+                        y+        iFMTFT ys+               ftmtfil+               ftmtfss++{---------------------------}
src/Data/RLE.hs view
@@ -14,7 +14,33 @@ -- = Run-length encoding (RLE)  -module Data.RLE where+module Data.RLE ( -- * To RLE functions+                  bytestringToBWTToRLEB,+                  bytestringToBWTToRLET,+                  textToBWTToRLEB,+                  textToBWTToRLET,+                  textBWTToRLEB,+                  bytestringBWTToRLEB,+                  textBWTToRLET,+                  bytestringBWTToRLET,+                  textToRLEB,+                  bytestringToRLEB,+                  textToRLET,+                  bytestringToRLET,+                  -- * From RLE functions+                  bytestringFromBWTFromRLEB,+                  bytestringFromBWTFromRLET,+                  textFromBWTFromRLEB,+                  textFromBWTFromRLET,+                  textBWTFromRLET,+                  bytestringBWTFromRLET,+                  textBWTFromRLEB,+                  bytestringBWTFromRLEB,+                  textFromRLEB,+                  bytestringFromRLEB,+                  textFromRLET,+                  bytestringFromRLET                   +                ) where  import Data.BWT import Data.BWT.Internal @@ -40,26 +66,26 @@  -- | Helper function for converting a 'ByteString' -- to a 'RLEB' via a 'BWT' first.-bytestringToBWTToRLEB :: ByteString ->-                         RLEB+bytestringToBWTToRLEB :: ByteString+                      -> RLEB bytestringToBWTToRLEB = bytestringBWTToRLEB . bytestringToBWT  -- | Helper function for converting a 'ByteString' -- to a 'RLET' via a 'BWT' first.-bytestringToBWTToRLET :: ByteString ->-                         RLET+bytestringToBWTToRLET :: ByteString+                      -> RLET bytestringToBWTToRLET = bytestringBWTToRLET . bytestringToBWT  -- | Helper function for converting a 'Text' -- to a 'RLEB' via a 'BWT' first.-textToBWTToRLEB :: Text ->-                   RLEB+textToBWTToRLEB :: Text+                -> RLEB textToBWTToRLEB = textBWTToRLEB . textToBWT  -- | Helper function for converting a 'Text' -- to a 'RLET' via a 'BWT' first.-textToBWTToRLET :: Text ->-                   RLET+textToBWTToRLET :: Text+                -> RLET textToBWTToRLET = textBWTToRLET . textToBWT  -- | Take a 'BWT' of 'Word8's and generate the@@ -283,7 +309,7 @@ bytestringFromRLEB :: RLEB                    -> Seq (Maybe ByteString) bytestringFromRLEB (RLEB DS.Empty) = DS.Empty-bytestringFromRLEB xs              = do+bytestringFromRLEB xs              =   CMST.runST $ seqFromRLEB xs  -- | Takes a 'RLET' and returns@@ -291,7 +317,7 @@ textFromRLET :: RLET              -> Seq (Maybe Text) textFromRLET (RLET DS.Empty) = DS.Empty-textFromRLET xs              = do+textFromRLET xs              =   CMST.runST $ seqFromRLET xs  -- | Takes a 'RLET' and returns
src/Data/RLE/Internal.hs view
@@ -71,14 +71,16 @@  {-toRLE (ByteString) functions.-} --- | Abstract 'RLESeqB' type utilizing a sequence.+-- | 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 :: STRLESeqB s (Maybe ByteString)+              -> Maybe ByteString+              -> ST s () pushSTRLESeqB s Nothing  = do   s2 <- readSTRef s   writeSTRef s (s2 DS.|> Nothing)@@ -94,7 +96,9 @@ type STRLETempB s a = STRef s (Maybe ByteString)  -- | State function to update 'STRLETempB'.-updateSTRLETempB :: STRLETempB s (Maybe ByteString) -> Maybe ByteString -> ST s ()+updateSTRLETempB :: STRLETempB s (Maybe ByteString)+                 -> Maybe ByteString+                 -> ST s () updateSTRLETempB s Nothing  = writeSTRef s Nothing updateSTRLETempB s (Just e) = writeSTRef s (Just e) @@ -106,7 +110,9 @@ type STRLECounterB s a = STRef s Int  -- | State function to update 'STRLECounterB'.-updateSTRLECounterB :: STRLECounterB s Int -> Int -> ST s ()+updateSTRLECounterB :: STRLECounterB s Int+                    -> Int+                    -> ST s () updateSTRLECounterB s e = writeSTRef s e  -- | State function to create empty 'STRLECounterB' type.@@ -204,14 +210,16 @@  {-toRLE (Text) functions.-} --- | Abstract 'RLESeqT' type utilizing a sequence.+-- | 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 :: STRLESeqT s (Maybe Text)+              -> (Maybe Text)+              -> ST s () pushSTRLESeqT s Nothing  = do   s2 <- readSTRef s   writeSTRef s (s2 DS.|> Nothing)@@ -227,7 +235,9 @@ type STRLETempT s a = STRef s (Maybe Text)  -- | State function to update 'STRLETempT'.-updateSTRLETempT :: STRLETempT s (Maybe Text) -> (Maybe Text) -> ST s ()+updateSTRLETempT :: STRLETempT s (Maybe Text)+                 -> (Maybe Text)+                 -> ST s () updateSTRLETempT s Nothing  = writeSTRef s Nothing updateSTRLETempT s (Just e) = writeSTRef s (Just e) @@ -239,7 +249,9 @@ type STRLECounterT s a = STRef s Int  -- | State function to update 'STRLECounterT'.-updateSTRLECounterT :: STRLECounterT s Int -> Int -> ST s ()+updateSTRLECounterT :: STRLECounterT s Int+                    -> Int+                    -> ST s () updateSTRLECounterT s e = writeSTRef s e  -- | State function to create empty 'STRLECounterT' type.@@ -247,8 +259,8 @@ emptySTRLECounterT = newSTRef (-1)  -- | Strict state monad function.-seqToRLET :: RLESeqT ->-             ST s RLESeqT+seqToRLET :: RLESeqT+          -> ST s RLESeqT seqToRLET DS.Empty      = do   trleseqstackempty  <- emptySTRLESeqT   trleseqstackemptyr <- readSTRef trleseqstackempty@@ -337,14 +349,16 @@  {-fromRLE (ByteString) functions.-} --- | Abstract 'FRLESeqB' type utilizing a sequence.+-- | 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 :: FSTRLESeqB s (Maybe ByteString)+               -> (Maybe ByteString)+               -> ST s () pushFSTRLESeqB s Nothing  = do   s2 <- readSTRef s   writeSTRef s (s2 DS.|> Nothing)@@ -412,14 +426,16 @@  {-fromRLE (Text) functions.-} --- | Abstract 'FRLESeqT' type utilizing a sequence.+-- | 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 :: FSTRLESeqT s (Maybe Text)+               -> (Maybe Text)+               -> ST s () pushFSTRLESeqT s Nothing  = do   s2 <- readSTRef s   writeSTRef s (s2 DS.|> Nothing)
text-compression.cabal view
@@ -20,7 +20,7 @@ -- PVP summary:     +-+------- breaking API changes --                  | | +----- non-breaking API additions --                  | | | +--- code changes with no API change-version:            0.1.0.9+version:            0.1.0.10  -- A short (one-line) description of the package. synopsis:           A text compression library.@@ -68,7 +68,9 @@     exposed-modules: Data.BWT.Internal,                      Data.BWT,                      Data.RLE.Internal,-                     Data.RLE+                     Data.RLE,+                     Data.MTF.Internal,+                     Data.MTF     -- Modules included in this library but not exported.     -- other-modules: