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


-- |
-- Module      :  Data.FMIndex
-- Copyright   :  (c) Matthew Mosior 2022
-- License     :  BSD-style
-- Maintainer  :  mattm.github@gmail.com
-- Portability :  portable
--
-- = Full-text Minute-space index (FM-index)
--
-- Users will get the most mileage by first compressing to a 'BWT'
-- on the initial 'ByteString' or 'Text' input before compressing to
-- a 'FMIndexB' or 'FMIndexT'.
--
-- To do this, users can use the 'bytestringToBWTToFMIndexB' and 'bytestringToBWTToFMIndexT' functions,
-- as well as the 'textToBWTToFMIndexB' and 'textToBWTToFMIndexT' functions.
--
-- The base functions for 'ByteString', 'bytestringToFMIndexB' and 'bytestringToFMIndexT' can be used to
-- convert a 'Seq' ('Maybe' 'ByteString') to a 'FMIndexB' and 'FMIndexT', respectively.
--
-- Likewise, the base functions for 'Text', 'textToFMIndexB' and 'textToFMIndexT' can be used to
-- convert a 'Seq' ('Maybe' 'Text') to a 'FMIndexB' and 'FMIndexT' respectively.
--
-- There are various other lower-level functions for interacting with the FMIndex implementation on 'ByteString' and 'Text' as well.
--
-- @"Data.FMIndex.Internal"@ contains efficient and stateful implementations of the FMIndex and Inverse FMIndex algorithms.


module Data.FMIndex ( -- * To FMIndex functions
                      bytestringToBWTToFMIndexB,
                      bytestringToBWTToFMIndexT,
                      textToBWTToFMIndexB,
                      textToBWTToFMIndexT,
                      textBWTToFMIndexB,
                      bytestringBWTToFMIndexB,
                      textBWTToFMIndexT,
                      bytestringBWTToFMIndexT,
                      textToFMIndexB,
                      bytestringToFMIndexB,
                      textToFMIndexT,
                      bytestringToFMIndexT,
                      -- * From FMIndex functions
                      bytestringFromBWTFromFMIndexB,
                      bytestringFromBWTFromFMIndexT,
                      textFromBWTFromFMIndexB,
                      textFromBWTFromFMIndexT,
                      textBWTFromFMIndexT,
                      bytestringBWTFromFMIndexT,
                      textBWTFromFMIndexB,
                      bytestringBWTFromFMIndexB,
                      textFromFMIndexB,
                      bytestringFromFMIndexB,
                      textFromFMIndexT,
                      bytestringFromFMIndexT
                    ) where

import Data.BWT
import Data.BWT.Internal
import Data.FMIndex.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


{-toFMIndex Function(s)-}

-- | Helper function for converting a 'ByteString'
-- to a 'FMIndexB' via a 'BWT' first.
bytestringToBWTToFMIndexB :: ByteString ->
                             FMIndexB
bytestringToBWTToFMIndexB :: ByteString -> FMIndexB
bytestringToBWTToFMIndexB = BWT Word8 -> FMIndexB
bytestringBWTToFMIndexB forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> BWT Word8
bytestringToBWT

-- | Helper function for converting a 'ByteString'
-- to a 'FMIndexT' via a 'BWT' first.
bytestringToBWTToFMIndexT :: ByteString ->
                             FMIndexT
bytestringToBWTToFMIndexT :: ByteString -> FMIndexT
bytestringToBWTToFMIndexT = BWT Word8 -> FMIndexT
bytestringBWTToFMIndexT forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> BWT Word8
bytestringToBWT

-- | Helper function for converting a 'Text'
-- to a 'FMIndexB' via a 'BWT' first.
textToBWTToFMIndexB :: Text ->
                       FMIndexB
textToBWTToFMIndexB :: Text -> FMIndexB
textToBWTToFMIndexB = TextBWT -> FMIndexB
textBWTToFMIndexB forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> TextBWT
textToBWT

-- | Helper function for converting a 'Text'
-- to a 'FMIndexT' via a 'BWT' first.
textToBWTToFMIndexT :: Text ->
                       FMIndexT
textToBWTToFMIndexT :: Text -> FMIndexT
textToBWTToFMIndexT = TextBWT -> FMIndexT
textBWTToFMIndexT forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> TextBWT
textToBWT

-- | Take a 'BWT' of 'Word8's and generate the
-- FM-index ('FMIndexB').
textBWTToFMIndexB :: TextBWT
                  -> FMIndexB
textBWTToFMIndexB :: TextBWT -> FMIndexB
textBWTToFMIndexB TextBWT
xs =
  Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
-> FMIndexB
FMIndexB (forall a. (forall s. ST s a) -> a
CMST.runST forall a b. (a -> b) -> a -> b
$ forall s.
PBFMIndexSeqB
-> ST s (Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString)))
seqToFMIndexB PBFMIndexSeqB
xss)
    where
      xss :: PBFMIndexSeqB
xss = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe Word8
x -> if | forall a. Maybe a -> Bool
isNothing Maybe Word8
x
                           -> forall a. Maybe a
Nothing
                           | Bool
otherwise
                           -> forall a. a -> Maybe a
Just         forall a b. (a -> b) -> a -> b
$
                              Word8 -> ByteString
BS.singleton forall a b. (a -> b) -> a -> b
$
                              forall a. HasCallStack => Maybe a -> a
fromJust Maybe Word8
x
                 )
            ((\(BWT Seq (Maybe Word8)
t) -> Seq (Maybe Word8)
t) forall a b. (a -> b) -> a -> b
$
            ((\(TextBWT BWT Word8
t) -> BWT Word8
t) TextBWT
xs))

-- | Take a 'BWT' of 'Word8's and generate the
-- FM-index ('FMIndexB').
bytestringBWTToFMIndexB :: BWT Word8
                        -> FMIndexB
bytestringBWTToFMIndexB :: BWT Word8 -> FMIndexB
bytestringBWTToFMIndexB BWT Word8
xs =
  Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
-> FMIndexB
FMIndexB (forall a. (forall s. ST s a) -> a
CMST.runST forall a b. (a -> b) -> a -> b
$ forall s.
PBFMIndexSeqB
-> ST s (Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString)))
seqToFMIndexB PBFMIndexSeqB
xss)
    where
      xss :: PBFMIndexSeqB
xss = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe Word8
x -> if | forall a. Maybe a -> Bool
isNothing Maybe Word8
x
                           -> forall a. Maybe a
Nothing
                           | Bool
otherwise
                           -> forall a. a -> Maybe a
Just         forall a b. (a -> b) -> a -> b
$
                              Word8 -> ByteString
BS.singleton forall a b. (a -> b) -> a -> b
$
                              forall a. HasCallStack => Maybe a -> a
fromJust Maybe Word8
x
                 )
            ((\(BWT Seq (Maybe Word8)
t) -> Seq (Maybe Word8)
t) BWT Word8
xs)

-- | Take a 'BWT' of 'Word8's and generate the
-- FM-index ('FMIndexB').
textBWTToFMIndexT :: TextBWT
                  -> FMIndexT
textBWTToFMIndexT :: TextBWT -> FMIndexT
textBWTToFMIndexT TextBWT
xs =
  Seq (Maybe Text, Seq (Int, Int, Maybe Text)) -> FMIndexT
FMIndexT (forall a. (forall s. ST s a) -> a
CMST.runST forall a b. (a -> b) -> a -> b
$ forall s.
PTFMIndexSeqT
-> ST s (Seq (Maybe Text, Seq (Int, Int, Maybe Text)))
seqToFMIndexT PTFMIndexSeqT
xss)
    where
      xss :: PTFMIndexSeqT
xss = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe Word8
x -> if | forall a. Maybe a -> Bool
isNothing Maybe Word8
x
                           -> forall a. Maybe a
Nothing
                           | Bool
otherwise
                           -> forall a. a -> Maybe a
Just           forall a b. (a -> b) -> a -> b
$
                              ByteString -> Text
DTE.decodeUtf8 forall a b. (a -> b) -> a -> b
$
                              Word8 -> ByteString
BS.singleton   forall a b. (a -> b) -> a -> b
$
                              forall a. HasCallStack => Maybe a -> a
fromJust Maybe Word8
x
                 )
            ((\(BWT Seq (Maybe Word8)
t) -> Seq (Maybe Word8)
t) forall a b. (a -> b) -> a -> b
$
            ((\(TextBWT BWT Word8
t) -> BWT Word8
t) TextBWT
xs))

-- | Take a 'BWT' of 'Word8's and generate the
-- FM-index ('FMIndexT').
bytestringBWTToFMIndexT :: BWT Word8
                        -> FMIndexT
bytestringBWTToFMIndexT :: BWT Word8 -> FMIndexT
bytestringBWTToFMIndexT BWT Word8
xs =
  Seq (Maybe Text, Seq (Int, Int, Maybe Text)) -> FMIndexT
FMIndexT (forall a. (forall s. ST s a) -> a
CMST.runST forall a b. (a -> b) -> a -> b
$ forall s.
PTFMIndexSeqT
-> ST s (Seq (Maybe Text, Seq (Int, Int, Maybe Text)))
seqToFMIndexT PTFMIndexSeqT
xss)
    where
      xss :: PTFMIndexSeqT
xss = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe Word8
x -> if | forall a. Maybe a -> Bool
isNothing Maybe Word8
x
                           -> forall a. Maybe a
Nothing
                           | Bool
otherwise
                           -> forall a. a -> Maybe a
Just           forall a b. (a -> b) -> a -> b
$
                              ByteString -> Text
DTE.decodeUtf8 forall a b. (a -> b) -> a -> b
$
                              Word8 -> ByteString
BS.singleton   forall a b. (a -> b) -> a -> b
$
                              forall a. HasCallStack => Maybe a -> a
fromJust Maybe Word8
x
                 )
            ((\(BWT Seq (Maybe Word8)
t) -> Seq (Maybe Word8)
t) BWT Word8
xs)

-- | Takes a 'Text' and returns the FM-index ('FMIndexB').
textToFMIndexB :: Seq (Maybe Text)
               -> FMIndexB
textToFMIndexB :: PTFMIndexSeqT -> FMIndexB
textToFMIndexB PTFMIndexSeqT
DS.Empty = Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
-> FMIndexB
FMIndexB forall a. Seq a
DS.Empty
textToFMIndexB PTFMIndexSeqT
xs       =
  Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
-> FMIndexB
FMIndexB (forall a. (forall s. ST s a) -> a
CMST.runST forall a b. (a -> b) -> a -> b
$ forall s.
PBFMIndexSeqB
-> ST s (Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString)))
seqToFMIndexB PBFMIndexSeqB
xss)
    where
      xss :: PBFMIndexSeqB
xss = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe Text
x -> if | forall a. Maybe a -> Bool
isNothing Maybe Text
x
                           -> forall a. Maybe a
Nothing
                           | Bool
otherwise
                           -> forall a. a -> Maybe a
Just            forall a b. (a -> b) -> a -> b
$
                               Text -> ByteString
DTE.encodeUtf8 forall a b. (a -> b) -> a -> b
$
                               forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
x
                 )
            PTFMIndexSeqT
xs

-- | Takes a 'Seq' of 'ByteString's and returns the FM-index ('FMIndexB').
bytestringToFMIndexB :: Seq (Maybe ByteString)
                     -> FMIndexB
bytestringToFMIndexB :: PBFMIndexSeqB -> FMIndexB
bytestringToFMIndexB PBFMIndexSeqB
DS.Empty = Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
-> FMIndexB
FMIndexB forall a. Seq a
DS.Empty
bytestringToFMIndexB PBFMIndexSeqB
xs       =
 Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
-> FMIndexB
FMIndexB (forall a. (forall s. ST s a) -> a
CMST.runST forall a b. (a -> b) -> a -> b
$ forall s.
PBFMIndexSeqB
-> ST s (Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString)))
seqToFMIndexB PBFMIndexSeqB
xs)

-- | Takes a 'Text' and returns the FM-index ('FMIndexT').
textToFMIndexT :: Seq (Maybe Text)
               -> FMIndexT
textToFMIndexT :: PTFMIndexSeqT -> FMIndexT
textToFMIndexT PTFMIndexSeqT
DS.Empty = Seq (Maybe Text, Seq (Int, Int, Maybe Text)) -> FMIndexT
FMIndexT forall a. Seq a
DS.Empty
textToFMIndexT PTFMIndexSeqT
xs       =
  Seq (Maybe Text, Seq (Int, Int, Maybe Text)) -> FMIndexT
FMIndexT (forall a. (forall s. ST s a) -> a
CMST.runST forall a b. (a -> b) -> a -> b
$ forall s.
PTFMIndexSeqT
-> ST s (Seq (Maybe Text, Seq (Int, Int, Maybe Text)))
seqToFMIndexT PTFMIndexSeqT
xs)

-- | Takes a 'ByteString' and returns the FM-index ('FMIndexT').
bytestringToFMIndexT :: Seq (Maybe ByteString)
                     -> FMIndexT
bytestringToFMIndexT :: PBFMIndexSeqB -> FMIndexT
bytestringToFMIndexT PBFMIndexSeqB
DS.Empty = Seq (Maybe Text, Seq (Int, Int, Maybe Text)) -> FMIndexT
FMIndexT forall a. Seq a
DS.Empty 
bytestringToFMIndexT PBFMIndexSeqB
xs       =
  Seq (Maybe Text, Seq (Int, Int, Maybe Text)) -> FMIndexT
FMIndexT (forall a. (forall s. ST s a) -> a
CMST.runST forall a b. (a -> b) -> a -> b
$ forall s.
PTFMIndexSeqT
-> ST s (Seq (Maybe Text, Seq (Int, Int, Maybe Text)))
seqToFMIndexT PTFMIndexSeqT
xss)
    where
      xss :: PTFMIndexSeqT
xss = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe ByteString
x -> if | forall a. Maybe a -> Bool
isNothing Maybe ByteString
x
                           -> forall a. Maybe a
Nothing
                           | Bool
otherwise
                           -> forall a. a -> Maybe a
Just           forall a b. (a -> b) -> a -> b
$
                              ByteString -> Text
DTE.decodeUtf8 forall a b. (a -> b) -> a -> b
$
                              forall a. HasCallStack => Maybe a -> a
fromJust Maybe ByteString
x
                 )
            PBFMIndexSeqB
xs

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


{-fromFMIndex function(s)-}

-- | Helper function for converting a 'BWT'ed 'FMIndexB'
-- back to the original 'ByteString'.
bytestringFromBWTFromFMIndexB :: FMIndexB
                              -> ByteString
bytestringFromBWTFromFMIndexB :: FMIndexB -> ByteString
bytestringFromBWTFromFMIndexB = BWT ByteString -> ByteString
bytestringFromByteStringBWT forall b c a. (b -> c) -> (a -> b) -> a -> c
. FMIndexB -> BWT ByteString
bytestringBWTFromFMIndexB

-- | Helper function for converting a 'BWT'ed 'FMIndexT'
-- back to the original 'ByteString'.
bytestringFromBWTFromFMIndexT :: FMIndexT
                              -> ByteString
bytestringFromBWTFromFMIndexT :: FMIndexT -> ByteString
bytestringFromBWTFromFMIndexT FMIndexT
xs = BWT ByteString -> ByteString
bytestringFromByteStringBWT forall a b. (a -> b) -> a -> b
$
                               forall a. Seq (Maybe a) -> BWT a
BWT                         forall a b. (a -> b) -> a -> b
$
                               forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe Text
x -> if | forall a. Maybe a -> Bool
isNothing Maybe Text
x
                                              -> forall a. Maybe a
Nothing
                                              | Bool
otherwise
                                              -> forall a. a -> Maybe a
Just           forall a b. (a -> b) -> a -> b
$
                                                 Text -> ByteString
DTE.encodeUtf8 forall a b. (a -> b) -> a -> b
$
                                                 forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
x
                                    )
                                                           forall a b. (a -> b) -> a -> b
$
                            ((\(BWT PTFMIndexSeqT
t) -> PTFMIndexSeqT
t) (FMIndexT -> BWT Text
textBWTFromFMIndexT FMIndexT
xs))

-- | Helper function for converting a 'BWT'ed 'FMIndexB'
-- back to the original 'Text'.
textFromBWTFromFMIndexB :: FMIndexB
                        -> Text
textFromBWTFromFMIndexB :: FMIndexB -> Text
textFromBWTFromFMIndexB = ByteString -> Text
DTE.decodeUtf8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. BWT ByteString -> ByteString
bytestringFromByteStringBWT forall b c a. (b -> c) -> (a -> b) -> a -> c
. FMIndexB -> BWT ByteString
bytestringBWTFromFMIndexB

-- | Helper function for converting a 'BWT'ed 'FMIndexT'
-- back to the original 'Text'.
textFromBWTFromFMIndexT :: FMIndexT
                        -> Text
textFromBWTFromFMIndexT :: FMIndexT -> Text
textFromBWTFromFMIndexT = ByteString -> Text
DTE.decodeUtf8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. BWT ByteString -> ByteString
bytestringFromByteStringBWT forall b c a. (b -> c) -> (a -> b) -> a -> c
. FMIndexT -> BWT ByteString
bytestringBWTFromFMIndexT

-- | Takes a 'FMIndexT' and returns
-- the 'BWT' of 'Text's.
textBWTFromFMIndexT :: FMIndexT
                    -> BWT Text
textBWTFromFMIndexT :: FMIndexT -> BWT Text
textBWTFromFMIndexT (FMIndexT Seq (Maybe Text, Seq (Int, Int, Maybe Text))
DS.Empty) = forall a. Seq (Maybe a) -> BWT a
BWT forall a. Seq a
DS.Empty
textBWTFromFMIndexT FMIndexT
xs                  =
  forall a. Seq (Maybe a) -> BWT a
BWT (FMIndexT -> PTFMIndexSeqT
seqFromFMIndexT FMIndexT
xs)

-- | Takes a 'FMIndexT' and returns
-- the 'BWT' of 'ByteString's.
bytestringBWTFromFMIndexT :: FMIndexT
                          -> BWT ByteString
bytestringBWTFromFMIndexT :: FMIndexT -> BWT ByteString
bytestringBWTFromFMIndexT (FMIndexT Seq (Maybe Text, Seq (Int, Int, Maybe Text))
DS.Empty) = forall a. Seq (Maybe a) -> BWT a
BWT forall a. Seq a
DS.Empty
bytestringBWTFromFMIndexT FMIndexT
xs                  = do
  let originalbwtb :: PTFMIndexSeqT
originalbwtb = FMIndexT -> PTFMIndexSeqT
seqFromFMIndexT FMIndexT
xs
  forall a. Seq (Maybe a) -> BWT a
BWT (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe Text
x -> if | forall a. Maybe a -> Bool
isNothing Maybe Text
x
                      -> forall a. Maybe a
Nothing
                      | Bool
otherwise
                      -> forall a. a -> Maybe a
Just           forall a b. (a -> b) -> a -> b
$
                         Text -> ByteString
DTE.encodeUtf8 forall a b. (a -> b) -> a -> b
$
                        forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
x
            ) PTFMIndexSeqT
originalbwtb)

-- | Takes a 'FMIndexB' and returns
-- the 'BWT' of 'Text's.
textBWTFromFMIndexB :: FMIndexB
                    -> BWT Text
textBWTFromFMIndexB :: FMIndexB -> BWT Text
textBWTFromFMIndexB (FMIndexB Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
DS.Empty) = forall a. Seq (Maybe a) -> BWT a
BWT forall a. Seq a
DS.Empty
textBWTFromFMIndexB FMIndexB
xs                  = do
  let originalbwtt :: PBFMIndexSeqB
originalbwtt = FMIndexB -> PBFMIndexSeqB
seqFromFMIndexB FMIndexB
xs
  forall a. Seq (Maybe a) -> BWT a
BWT (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe ByteString
x -> if | forall a. Maybe a -> Bool
isNothing Maybe ByteString
x
                      -> forall a. Maybe a
Nothing
                      | Bool
otherwise
                      -> forall a. a -> Maybe a
Just           forall a b. (a -> b) -> a -> b
$
                         ByteString -> Text
DTE.decodeUtf8 forall a b. (a -> b) -> a -> b
$
                        forall a. HasCallStack => Maybe a -> a
fromJust Maybe ByteString
x
            ) PBFMIndexSeqB
originalbwtt)

-- | Take a 'FMIndexB' and returns
-- the 'BWT' of 'ByteString's.
bytestringBWTFromFMIndexB :: FMIndexB
                          -> BWT ByteString
bytestringBWTFromFMIndexB :: FMIndexB -> BWT ByteString
bytestringBWTFromFMIndexB (FMIndexB Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
DS.Empty) = forall a. Seq (Maybe a) -> BWT a
BWT forall a. Seq a
DS.Empty
bytestringBWTFromFMIndexB FMIndexB
xs              =
  forall a. Seq (Maybe a) -> BWT a
BWT (FMIndexB -> PBFMIndexSeqB
seqFromFMIndexB FMIndexB
xs)

-- | Takes a 'FMIndexB' and returns
-- the original 'Seq' of 'Text's.
textFromFMIndexB :: FMIndexB
                 -> Seq (Maybe Text)
textFromFMIndexB :: FMIndexB -> PTFMIndexSeqT
textFromFMIndexB (FMIndexB Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
DS.Empty) = forall a. Seq a
DS.Empty
textFromFMIndexB FMIndexB
xs                  = do
  let originalt :: PBFMIndexSeqB
originalt = FMIndexB -> PBFMIndexSeqB
seqFromFMIndexB FMIndexB
xs
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe ByteString
x -> if | forall a. Maybe a -> Bool
isNothing Maybe ByteString
x
                 -> forall a. Maybe a
Nothing
                 | Bool
otherwise
                 -> forall a. a -> Maybe a
Just           forall a b. (a -> b) -> a -> b
$
                    ByteString -> Text
DTE.decodeUtf8 forall a b. (a -> b) -> a -> b
$
                    forall a. HasCallStack => Maybe a -> a
fromJust Maybe ByteString
x
       ) PBFMIndexSeqB
originalt

-- | Takes a 'FMIndexB' and returns
-- the original 'Seq' of 'ByteString's.
bytestringFromFMIndexB :: FMIndexB
                       -> Seq (Maybe ByteString)
bytestringFromFMIndexB :: FMIndexB -> PBFMIndexSeqB
bytestringFromFMIndexB (FMIndexB Seq (Maybe ByteString, Seq (Int, Int, Maybe ByteString))
DS.Empty) = forall a. Seq a
DS.Empty
bytestringFromFMIndexB FMIndexB
xs                  =
  FMIndexB -> PBFMIndexSeqB
seqFromFMIndexB FMIndexB
xs

-- | Takes a 'FMIndexT' and returns
-- the original 'Seq' of 'Text's.
textFromFMIndexT :: FMIndexT
                 -> Seq (Maybe Text)
textFromFMIndexT :: FMIndexT -> PTFMIndexSeqT
textFromFMIndexT (FMIndexT Seq (Maybe Text, Seq (Int, Int, Maybe Text))
DS.Empty) = forall a. Seq a
DS.Empty
textFromFMIndexT FMIndexT
xs                  =
  FMIndexT -> PTFMIndexSeqT
seqFromFMIndexT FMIndexT
xs

-- | Takes a 'FMIndexT' and returns
-- the original 'Seq' of 'ByteString's.
bytestringFromFMIndexT :: FMIndexT
                       -> Seq (Maybe ByteString)
bytestringFromFMIndexT :: FMIndexT -> PBFMIndexSeqB
bytestringFromFMIndexT (FMIndexT Seq (Maybe Text, Seq (Int, Int, Maybe Text))
DS.Empty) = forall a. Seq a
DS.Empty
bytestringFromFMIndexT FMIndexT
xs                  = do
  let originalb :: PTFMIndexSeqT
originalb = FMIndexT -> PTFMIndexSeqT
seqFromFMIndexT FMIndexT
xs
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Maybe Text
x -> if | forall a. Maybe a -> Bool
isNothing Maybe Text
x
                 -> forall a. Maybe a
Nothing
                 | Bool
otherwise
                 -> forall a. a -> Maybe a
Just           forall a b. (a -> b) -> a -> b
$
                    Text -> ByteString
DTE.encodeUtf8 forall a b. (a -> b) -> a -> b
$
                    forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
x
       ) PTFMIndexSeqT
originalb

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