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 +4/−0
- src/Data/BWT.hs +23/−12
- src/Data/BWT/Internal.hs +25/−21
- src/Data/MTF.hs +344/−0
- src/Data/MTF/Internal.hs +518/−0
- src/Data/RLE.hs +37/−11
- src/Data/RLE/Internal.hs +30/−14
- text-compression.cabal +4/−2
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: