-- |
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE TypeFamilies #-}

module Talash.Chunked (module Talash.Chunked , module Export) where

import Control.Concurrent (forkIO)
import Control.Concurrent.MVar
import Data.Bit
import qualified Data.Set as DS
import qualified Data.Text as T
import Data.Text.AhoCorasick.Automaton as Export (CaseSensitivity(..))
import qualified Data.Vector as V
import Data.Vector.Algorithms.Intro (sort)
import qualified Data.Vector.Mutable as MV
import qualified Data.Vector.Sized as SV
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as M
import qualified Data.Vector.Unboxed.Mutable.Sized as MS
import qualified Data.Vector.Unboxed.Sized as S
import Lens.Micro.TH (makeLenses)
import qualified System.IO.Streams as I
import Talash.Core as Export hiding (match , makeMatcher)
import Talash.Intro hiding (splitAt)
import Talash.ScoredMatch as Export

newtype Chunks (n:: Nat) = Chunks { forall (n :: Nat). Chunks n -> Vector (Vector n Text)
chunks ::  V.Vector (SV.Vector n Text)} deriving (Chunks n -> Chunks n -> Bool
forall (n :: Nat). Chunks n -> Chunks n -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Chunks n -> Chunks n -> Bool
$c/= :: forall (n :: Nat). Chunks n -> Chunks n -> Bool
== :: Chunks n -> Chunks n -> Bool
$c== :: forall (n :: Nat). Chunks n -> Chunks n -> Bool
Eq , Chunks n -> Chunks n -> Bool
Chunks n -> Chunks n -> Ordering
Chunks n -> Chunks n -> Chunks n
forall (n :: Nat). Eq (Chunks n)
forall (n :: Nat). Chunks n -> Chunks n -> Bool
forall (n :: Nat). Chunks n -> Chunks n -> Ordering
forall (n :: Nat). Chunks n -> Chunks n -> Chunks n
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Chunks n -> Chunks n -> Chunks n
$cmin :: forall (n :: Nat). Chunks n -> Chunks n -> Chunks n
max :: Chunks n -> Chunks n -> Chunks n
$cmax :: forall (n :: Nat). Chunks n -> Chunks n -> Chunks n
>= :: Chunks n -> Chunks n -> Bool
$c>= :: forall (n :: Nat). Chunks n -> Chunks n -> Bool
> :: Chunks n -> Chunks n -> Bool
$c> :: forall (n :: Nat). Chunks n -> Chunks n -> Bool
<= :: Chunks n -> Chunks n -> Bool
$c<= :: forall (n :: Nat). Chunks n -> Chunks n -> Bool
< :: Chunks n -> Chunks n -> Bool
$c< :: forall (n :: Nat). Chunks n -> Chunks n -> Bool
compare :: Chunks n -> Chunks n -> Ordering
$ccompare :: forall (n :: Nat). Chunks n -> Chunks n -> Ordering
Ord , Int -> Chunks n -> ShowS
forall (n :: Nat). Int -> Chunks n -> ShowS
forall (n :: Nat). [Chunks n] -> ShowS
forall (n :: Nat). Chunks n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Chunks n] -> ShowS
$cshowList :: forall (n :: Nat). [Chunks n] -> ShowS
show :: Chunks n -> String
$cshow :: forall (n :: Nat). Chunks n -> String
showsPrec :: Int -> Chunks n -> ShowS
$cshowsPrec :: forall (n :: Nat). Int -> Chunks n -> ShowS
Show)
type MatchSetSized n = DS.Set (ScoredMatchSized n)

data Ocassion = ChunkSearched | QueryDone | NewQuery | SearchDone deriving (Ocassion -> Ocassion -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ocassion -> Ocassion -> Bool
$c/= :: Ocassion -> Ocassion -> Bool
== :: Ocassion -> Ocassion -> Bool
$c== :: Ocassion -> Ocassion -> Bool
Eq , Eq Ocassion
Ocassion -> Ocassion -> Bool
Ocassion -> Ocassion -> Ordering
Ocassion -> Ocassion -> Ocassion
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Ocassion -> Ocassion -> Ocassion
$cmin :: Ocassion -> Ocassion -> Ocassion
max :: Ocassion -> Ocassion -> Ocassion
$cmax :: Ocassion -> Ocassion -> Ocassion
>= :: Ocassion -> Ocassion -> Bool
$c>= :: Ocassion -> Ocassion -> Bool
> :: Ocassion -> Ocassion -> Bool
$c> :: Ocassion -> Ocassion -> Bool
<= :: Ocassion -> Ocassion -> Bool
$c<= :: Ocassion -> Ocassion -> Bool
< :: Ocassion -> Ocassion -> Bool
$c< :: Ocassion -> Ocassion -> Bool
compare :: Ocassion -> Ocassion -> Ordering
$ccompare :: Ocassion -> Ocassion -> Ordering
Ord , Int -> Ocassion -> ShowS
[Ocassion] -> ShowS
Ocassion -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ocassion] -> ShowS
$cshowList :: [Ocassion] -> ShowS
show :: Ocassion -> String
$cshow :: Ocassion -> String
showsPrec :: Int -> Ocassion -> ShowS
$cshowsPrec :: Int -> Ocassion -> ShowS
Show)

data SearchStateSized (n :: Nat) a = SearchStateSized { forall (n :: Nat) a. SearchStateSized n a -> Text
_currentQuery :: {-# UNPACK #-} !Text
                                                      , forall (n :: Nat) a. SearchStateSized n a -> Text
_prevQuery :: {-# UNPACK #-} !Text
                                                      , forall (n :: Nat) a. SearchStateSized n a -> Int
_chunkNumber :: {-# UNPACK #-} !Int
                                                      , forall (n :: Nat) a. SearchStateSized n a -> Int
_totalMatches :: {-# UNPACK #-} !Int
                                                      , forall (n :: Nat) a. SearchStateSized n a -> Bool
_newMatches ::  !Bool
                                                      , forall (n :: Nat) a. SearchStateSized n a -> Bool
_done :: !Bool
                                                      , forall (n :: Nat) a. SearchStateSized n a -> MatchSetSized n
_matchSet :: !(MatchSetSized n)}
makeLenses ''SearchStateSized

data SearchFunctions a b = SearchFunctions { forall a b. SearchFunctions a b -> Text -> Matcher a
_makeMatcher :: Text -> Matcher a
                                           , forall a b.
SearchFunctions a b
-> forall (n :: Nat).
   KnownNat n =>
   MatcherSized n a -> Text -> Maybe (MatchFull n)
_match :: forall n. KnownNat n => MatcherSized n a -> Text -> Maybe (MatchFull n)
                           -- | Given the matcher @m@, the matched string @t@ and the indices of matches in @t@ divide @t@ in alternating strings that are a matches
                           --   and the gap between these matches. The first of these is always a gap and can be empty. The rest should be non empty.
                                           , forall a b.
SearchFunctions a b
-> forall (n :: Nat).
   KnownNat n =>
   (Bool -> Text -> b)
   -> MatcherSized n a -> Text -> Vector n Int -> [b]
_display :: forall n. KnownNat n => (Bool -> Text -> b) -> MatcherSized n a -> Text -> S.Vector n Int -> [b] }
makeLenses ''SearchFunctions

data SearchReport = SearchReport { SearchReport -> Ocassion
_ocassion :: Ocassion , SearchReport -> Bool
_hasNewMatches :: Bool , SearchReport -> Int
_nummatches :: Int , SearchReport -> Text
_searchedTerm :: Text}
makeLenses ''SearchReport

-- | The constant environment in which the search runs.
data SearchEnv n a b = SearchEnv { forall (n :: Nat) a b. SearchEnv n a b -> SearchFunctions a b
_searchFunctions :: SearchFunctions a b  -- ^ The functions used to find and display matches.
                                 , forall (n :: Nat) a b.
SearchEnv n a b
-> forall (n :: Nat) (m :: Nat).
   (KnownNat n, KnownNat m) =>
   Chunks n
   -> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ()
_send :: forall n m. (KnownNat n , KnownNat m) => Chunks n -> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ()
                                 , forall (n :: Nat) a b. SearchEnv n a b -> Int
_maxMatches :: Int
                                 , forall (n :: Nat) a b. SearchEnv n a b -> Chunks n
_candidates :: Chunks n
                                 , forall (n :: Nat) a b. SearchEnv n a b -> MVar (Maybe Text)
_query :: MVar (Maybe Text)
                                 , forall (n :: Nat) a b. SearchEnv n a b -> IOVector (Vector n Bit)
_allMatches :: M.IOVector (S.Vector n Bit) }
makeLenses ''SearchEnv

{-# INLINABLE (!) #-}
(!) :: KnownNat n => Chunks n -> ChunkIndex -> Text
! :: forall (n :: Nat). KnownNat n => Chunks n -> ChunkIndex -> Text
(!) (Chunks Vector (Vector n Text)
v) (ChunkIndex Int
i Int
j) = forall a. Vector a -> Int -> a
V.unsafeIndex (forall (n :: Nat) a. Vector n a -> Vector a
SV.fromSized forall a b. (a -> b) -> a -> b
$ forall a. Vector a -> Int -> a
V.unsafeIndex Vector (Vector n Text)
v Int
i) Int
j

{-# INLINE getChunk #-}
getChunk :: Int -> Chunks n -> SV.Vector n Text
getChunk :: forall (n :: Nat). Int -> Chunks n -> Vector n Text
getChunk Int
i (Chunks Vector (Vector n Text)
f) = forall a. Vector a -> Int -> a
V.unsafeIndex Vector (Vector n Text)
f Int
i

{-# INLINE matchChunk #-}
matchChunk :: forall n m a. (KnownNat n , KnownNat m) => (MatcherSized n a -> Text -> Maybe (MatchFull n)) -> MatcherSized n a -> Int -> SV.Vector m Text
  -> S.Vector m Bit -> (S.Vector m Bit , MatchSetSized n)
matchChunk :: forall (n :: Nat) (m :: Nat) a.
(KnownNat n, KnownNat m) =>
(MatcherSized n a -> Text -> Maybe (MatchFull n))
-> MatcherSized n a
-> Int
-> Vector m Text
-> Vector m Bit
-> (Vector m Bit, MatchSetSized n)
matchChunk MatcherSized n a -> Text -> Maybe (MatchFull n)
fun MatcherSized n a
m Int
ci Vector m Text
v Vector m Bit
i = forall a. (forall s. ST s a) -> a
runST forall a b. (a -> b) -> a -> b
$ forall (n :: Nat) (m :: Nat) a s.
(KnownNat n, KnownNat m) =>
(MatcherSized n a -> Text -> Maybe (MatchFull n))
-> MatcherSized n a
-> Int
-> Vector m Text
-> Vector m Bit
-> ST s (Vector m Bit, MatchSetSized n)
matchChunkM MatcherSized n a -> Text -> Maybe (MatchFull n)
fun MatcherSized n a
m Int
ci Vector m Text
v Vector m Bit
i

{-# INLINEABLE matchChunkM #-}
matchChunkM :: forall n m a s. (KnownNat n , KnownNat m) => (MatcherSized n a -> Text -> Maybe (MatchFull n)) -> MatcherSized n a -> Int -> SV.Vector m Text
  -> S.Vector m Bit -> ST s (S.Vector m Bit , MatchSetSized n)
matchChunkM :: forall (n :: Nat) (m :: Nat) a s.
(KnownNat n, KnownNat m) =>
(MatcherSized n a -> Text -> Maybe (MatchFull n))
-> MatcherSized n a
-> Int
-> Vector m Text
-> Vector m Bit
-> ST s (Vector m Bit, MatchSetSized n)
matchChunkM MatcherSized n a -> Text -> Maybe (MatchFull n)
fun MatcherSized n a
m = Int
-> Vector m Text
-> Vector m Bit
-> ST s (Vector m Bit, Set (ScoredMatchSized n))
go
  where
    go :: Int
-> Vector m Text
-> Vector m Bit
-> ST s (Vector m Bit, Set (ScoredMatchSized n))
go Int
ci Vector m Text
v Vector m Bit
i = MVector m s Bit -> ST s (Vector m Bit, Set (ScoredMatchSized n))
doMatching forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (n :: Nat) (m :: * -> *) a.
(KnownNat n, PrimMonad m, Unbox a) =>
a -> m (MVector n (PrimState m) a)
MS.replicate (Bool -> Bit
Bit Bool
False)
      where
        nzero :: Bool
nzero = forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy :: Proxy n) forall a. Eq a => a -> a -> Bool
== Integer
0
        doMatching :: MVector m s Bit -> ST s (Vector m Bit, Set (ScoredMatchSized n))
doMatching MVector m s Bit
mbv = Set (ScoredMatchSized n)
-> ST s (Vector m Bit, Set (ScoredMatchSized n))
freezeAndDone forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *) b a.
(Monad m, Unbox b) =>
(a -> Int -> b -> m a) -> a -> Vector b -> m a
U.ifoldM' Set (ScoredMatchSized n)
-> Int -> Bit -> ST s (Set (ScoredMatchSized n))
collectAndWrite forall a. Set a
DS.empty (forall (n :: Nat) a. Vector n a -> Vector a
S.fromSized Vector m Bit
i)
          where
            umbv :: MVector s Bit
umbv = forall (n :: Nat) s a. MVector n s a -> MVector s a
MS.fromSized MVector m s Bit
mbv
            freezeAndDone :: Set (ScoredMatchSized n)
-> ST s (Vector m Bit, Set (ScoredMatchSized n))
freezeAndDone Set (ScoredMatchSized n)
mset = ( , Set (ScoredMatchSized n)
mset) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a (n :: Nat).
(PrimMonad m, Unbox a) =>
MVector n (PrimState m) a -> m (Vector n a)
S.unsafeFreeze MVector m s Bit
mbv
            collectAndWrite :: Set (ScoredMatchSized n)
-> Int -> Bit -> ST s (Set (ScoredMatchSized n))
collectAndWrite Set (ScoredMatchSized n)
x Int
_ (Bit Bool
False) = forall (f :: * -> *) a. Applicative f => a -> f a
pure Set (ScoredMatchSized n)
x
            collectAndWrite Set (ScoredMatchSized n)
x Int
j (Bit Bool
True)
              | Maybe (MatchFull n)
Nothing   <- Maybe (MatchFull n)
res   = forall (f :: * -> *) a. Applicative f => a -> f a
pure Set (ScoredMatchSized n)
x
              | Just MatchFull n
mtch <- Maybe (MatchFull n)
res   = forall (m :: * -> *).
PrimMonad m =>
MVector (PrimState m) Bit -> Int -> m ()
unsafeFlipBit MVector s Bit
umbv Int
j forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> forall a. Ord a => a -> Set a -> Set a
DS.insert (MatchFull n -> ScoredMatchSized n
conv MatchFull n
mtch) Set (ScoredMatchSized n)
x
              where
                res :: Maybe (MatchFull n)
res
                  | Bool
nzero      = if forall (n :: Nat) a. Vector n a -> Int -> a
SV.unsafeIndex Vector m Text
v Int
j forall a. Eq a => a -> a -> Bool
== Text
"" then forall a. Maybe a
Nothing else MatcherSized n a -> Text -> Maybe (MatchFull n)
fun MatcherSized n a
m forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a. Vector n a -> Int -> a
SV.unsafeIndex Vector m Text
v forall a b. (a -> b) -> a -> b
$ Int
j
                  | Bool
otherwise  = MatcherSized n a -> Text -> Maybe (MatchFull n)
fun MatcherSized n a
m forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a. Vector n a -> Int -> a
SV.unsafeIndex Vector m Text
v forall a b. (a -> b) -> a -> b
$ Int
j
                conv :: MatchFull n -> ScoredMatchSized n
conv (MatchFull Int
k Vector n Int
w) = forall (n :: Nat).
Down Int -> ChunkIndex -> Vector n Int -> ScoredMatchSized n
ScoredMatchSized (forall a. a -> Down a
Down Int
k) (Int -> Int -> ChunkIndex
ChunkIndex Int
ci Int
j) Vector n Int
w

{-# INLINABLE resetMatches #-}
resetMatches :: forall n m a b. KnownNat n => SearchEnv n a b -> SearchStateSized m a -> IO ()
resetMatches :: forall (n :: Nat) (m :: Nat) a b.
KnownNat n =>
SearchEnv n a b -> SearchStateSized m a -> IO ()
resetMatches SearchEnv n a b
env SearchStateSized m a
state
  | Text -> Text -> Bool
T.isInfixOf (SearchStateSized m a
state forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Text Text
prevQuery) (SearchStateSized m a
state forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Text Text
currentQuery) = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  | Bool
otherwise                                                = forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> a -> m ()
M.set (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b.
Lens' (SearchEnv n a b) (IOVector (Vector n Bit))
allMatches) (forall (n :: Nat) a. (KnownNat n, Unbox a) => a -> Vector n a
S.replicate Bit
1)

{-# INLINABLE  searchNextChunk #-}
searchNextChunk :: (KnownNat n , KnownNat m) => SearchEnv n a b -> MatcherSized m a -> SearchStateSized m a -> IO (SearchStateSized m a)
searchNextChunk :: forall (n :: Nat) (m :: Nat) a b.
(KnownNat n, KnownNat m) =>
SearchEnv n a b
-> MatcherSized m a
-> SearchStateSized m a
-> IO (SearchStateSized m a)
searchNextChunk SearchEnv n a b
env MatcherSized m a
matcher SearchStateSized m a
state = (Vector n Bit, Set (ScoredMatchSized m))
-> IO (SearchStateSized m a)
nextstate forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector n Bit -> (Vector n Bit, Set (ScoredMatchSized m))
getMatches forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
M.read (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b.
Lens' (SearchEnv n a b) (IOVector (Vector n Bit))
allMatches) Int
i
  where
    i :: Int
i          = SearchStateSized m a
state forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Int Int
chunkNumber
    getMatches :: Vector n Bit -> (Vector n Bit, Set (ScoredMatchSized m))
getMatches = forall (n :: Nat) (m :: Nat) a.
(KnownNat n, KnownNat m) =>
(MatcherSized n a -> Text -> Maybe (MatchFull n))
-> MatcherSized n a
-> Int
-> Vector m Text
-> Vector m Bit
-> (Vector m Bit, MatchSetSized n)
matchChunk (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b b.
Lens
  (SearchEnv n a b)
  (SearchEnv n a b)
  (SearchFunctions a b)
  (SearchFunctions a b)
searchFunctions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b (n :: Nat).
KnownNat n =>
SimpleGetter
  (SearchFunctions a b)
  (MatcherSized n a -> Text -> Maybe (MatchFull n))
match) MatcherSized m a
matcher Int
i (forall (n :: Nat). Int -> Chunks n -> Vector n Text
getChunk Int
i (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) (Chunks n)
candidates))
    nextstate :: (Vector n Bit, Set (ScoredMatchSized m))
-> IO (SearchStateSized m a)
nextstate (Vector n Bit
js , Set (ScoredMatchSized m)
mtchs) = forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
M.write (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b.
Lens' (SearchEnv n a b) (IOVector (Vector n Bit))
allMatches) Int
i Vector n Bit
js forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> (forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Int Int
chunkNumber (forall a. Num a => a -> a -> a
+ Int
1) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (Set (ScoredMatchSized m)) -> SearchStateSized m Any
updateAndSend forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set (ScoredMatchSized m)
-> Set (ScoredMatchSized m) -> Maybe (Set (ScoredMatchSized m))
mergedMatches (SearchStateSized m a
state forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a (n :: Nat) a.
Lens
  (SearchStateSized n a)
  (SearchStateSized n a)
  (MatchSetSized n)
  (MatchSetSized n)
matchSet) forall a b. (a -> b) -> a -> b
$ Set (ScoredMatchSized m)
mtchs)
      where
        mergedMatches :: Set (ScoredMatchSized m)
-> Set (ScoredMatchSized m) -> Maybe (Set (ScoredMatchSized m))
mergedMatches Set (ScoredMatchSized m)
curr Set (ScoredMatchSized m)
new = if Bool -> Bool
not (forall a. Set a -> Bool
DS.null Set (ScoredMatchSized m)
new) Bool -> Bool -> Bool
&& (forall a. Set a -> Int
DS.size Set (ScoredMatchSized m)
curr forall a. Ord a => a -> a -> Bool
< SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) Int
maxMatches Bool -> Bool -> Bool
|| forall a. Set a -> Maybe a
DS.lookupMax Set (ScoredMatchSized m)
curr forall a. Ord a => a -> a -> Bool
> forall a. Set a -> Maybe a
DS.lookupMin Set (ScoredMatchSized m)
new)
                                                         then forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> Set a -> Set a
DS.take (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) Int
maxMatches) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => Set a -> Set a -> Set a
DS.union Set (ScoredMatchSized m)
curr forall a b. (a -> b) -> a -> b
$ Set (ScoredMatchSized m)
new else forall a. Maybe a
Nothing
        updateAndSend :: Maybe (Set (ScoredMatchSized m)) -> SearchStateSized m Any
updateAndSend = forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Int Int
totalMatches (forall a. Num a => a -> a -> a
+ forall a. Set a -> Int
DS.size Set (ScoredMatchSized m)
mtchs) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall s t a b. ASetter s t a b -> b -> s -> t
set forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Bool Bool
newMatches Bool
False SearchStateSized m a
state) (\Set (ScoredMatchSized m)
mset -> forall s t a b. ASetter s t a b -> b -> s -> t
set forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Bool Bool
newMatches Bool
True (forall s t a b. ASetter s t a b -> b -> s -> t
set forall (n :: Nat) a (n :: Nat) a.
Lens
  (SearchStateSized n a)
  (SearchStateSized n a)
  (MatchSetSized n)
  (MatchSetSized n)
matchSet Set (ScoredMatchSized m)
mset SearchStateSized m a
state))

matcherLoop :: (KnownNat n , KnownNat m) => SearchEnv n a b -> Text -> Text -> MatcherSized m a -> IO (Maybe Text)
matcherLoop :: forall (n :: Nat) (m :: Nat) a b.
(KnownNat n, KnownNat m) =>
SearchEnv n a b
-> Text -> Text -> MatcherSized m a -> IO (Maybe Text)
matcherLoop SearchEnv n a b
env Text
qry Text
prev MatcherSized m a
matcher = forall (n :: Nat) (m :: Nat) a b.
KnownNat n =>
SearchEnv n a b -> SearchStateSized m a -> IO ()
resetMatches SearchEnv n a b
env SearchStateSized m a
initstate forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> SearchStateSized m a -> IO (Maybe Text)
loop SearchStateSized m a
initstate
  where
    initstate :: SearchStateSized m a
initstate = forall (n :: Nat) a.
Text
-> Text
-> Int
-> Int
-> Bool
-> Bool
-> MatchSetSized n
-> SearchStateSized n a
SearchStateSized Text
qry Text
prev Int
0 Int
0 Bool
False Bool
False forall a. Set a
DS.empty
    loop :: SearchStateSized m a -> IO (Maybe Text)
loop SearchStateSized m a
state = Maybe (Maybe Text) -> IO (Maybe Text)
step forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. MVar a -> IO (Maybe a)
tryTakeMVar (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) (MVar (Maybe Text))
query)
      where
        step :: Maybe (Maybe Text) -> IO (Maybe Text)
step Maybe (Maybe Text)
x
          | Just Maybe Text
Nothing <- Maybe (Maybe Text)
x      = Ocassion -> IO ()
doSend Ocassion
SearchDone forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> forall a. Maybe a
Nothing
          | Bool
inrange , Maybe (Maybe Text)
Nothing <- Maybe (Maybe Text)
x = Ocassion -> IO ()
doSend Ocassion
ChunkSearched forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (SearchStateSized m a -> IO (Maybe Text)
loop forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (n :: Nat) (m :: Nat) a b.
(KnownNat n, KnownNat m) =>
SearchEnv n a b
-> MatcherSized m a
-> SearchStateSized m a
-> IO (SearchStateSized m a)
searchNextChunk SearchEnv n a b
env MatcherSized m a
matcher SearchStateSized m a
state)
          | Just (Just Text
t) <- Maybe (Maybe Text)
x     = Ocassion -> IO ()
doSend Ocassion
NewQuery forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> forall a. a -> Maybe a
Just Text
t
          | Bool
otherwise              = Ocassion -> IO ()
doSend Ocassion
QueryDone forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall a. MVar a -> IO a
takeMVar (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) (MVar (Maybe Text))
query)
          where
            report :: Ocassion -> SearchReport
report Ocassion
b = Ocassion -> Bool -> Int -> Text -> SearchReport
SearchReport Ocassion
b (SearchStateSized m a
state forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Bool Bool
newMatches) (SearchStateSized m a
state forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Int Int
totalMatches) Text
qry
            doSend :: Ocassion -> IO ()
doSend Ocassion
b = (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b (n :: Nat) (m :: Nat).
(KnownNat n, KnownNat m) =>
SimpleGetter
  (SearchEnv n a b)
  (Chunks n
   -> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ())
send) (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) (Chunks n)
candidates) (Ocassion -> SearchReport
report Ocassion
b) MatcherSized m a
matcher (SearchStateSized m a
state forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a (n :: Nat) a.
Lens
  (SearchStateSized n a)
  (SearchStateSized n a)
  (MatchSetSized n)
  (MatchSetSized n)
matchSet)
            inrange :: Bool
inrange = SearchStateSized m a
state forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a a.
Lens (SearchStateSized n a) (SearchStateSized n a) Int Int
chunkNumber forall a. Ord a => a -> a -> Bool
< (forall a. Vector a -> Int
V.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat). Chunks n -> Vector (Vector n Text)
chunks forall a b. (a -> b) -> a -> b
$ SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) (Chunks n)
candidates)

searchEnv :: KnownNat n => SearchFunctions a b -> Int -> (forall n m. (KnownNat n , KnownNat m) => Chunks n -> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ())
  -> Chunks n -> IO (SearchEnv n a b)
searchEnv :: forall (n :: Nat) a b.
KnownNat n =>
SearchFunctions a b
-> Int
-> (forall (n :: Nat) (m :: Nat).
    (KnownNat n, KnownNat m) =>
    Chunks n
    -> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ())
-> Chunks n
-> IO (SearchEnv n a b)
searchEnv SearchFunctions a b
funs Int
n forall (n :: Nat) (m :: Nat).
(KnownNat n, KnownNat m) =>
Chunks n
-> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ()
sender Chunks n
chks = forall (n :: Nat) a b.
SearchFunctions a b
-> (forall (n :: Nat) (m :: Nat).
    (KnownNat n, KnownNat m) =>
    Chunks n
    -> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ())
-> Int
-> Chunks n
-> MVar (Maybe Text)
-> IOVector (Vector n Bit)
-> SearchEnv n a b
SearchEnv SearchFunctions a b
funs forall (n :: Nat) (m :: Nat).
(KnownNat n, KnownNat m) =>
Chunks n
-> SearchReport -> MatcherSized m a -> MatchSetSized m -> IO ()
sender Int
n Chunks n
chks forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. IO (MVar a)
newEmptyMVar forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
M.replicate (forall a. Vector a -> Int
V.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat). Chunks n -> Vector (Vector n Text)
chunks forall a b. (a -> b) -> a -> b
$ Chunks n
chks) (forall (n :: Nat) a. (KnownNat n, Unbox a) => a -> Vector n a
S.replicate Bit
1)

searchLoop :: KnownNat n => SearchEnv n a b -> IO ()
searchLoop :: forall (n :: Nat) a b. KnownNat n => SearchEnv n a b -> IO ()
searchLoop SearchEnv n a b
env = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (Text -> Text -> IO ()
loop Text
"") forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. MVar a -> IO a
takeMVar (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) (MVar (Maybe Text))
query)
  where
    loop :: Text -> Text -> IO ()
loop Text
prev Text
qry
      | (Matcher MatcherSized n a
m) <- (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b b.
Lens
  (SearchEnv n a b)
  (SearchEnv n a b)
  (SearchFunctions a b)
  (SearchFunctions a b)
searchFunctions forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Lens' (SearchFunctions a b) (Text -> Matcher a)
makeMatcher) Text
qry = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (Text -> Text -> IO ()
loop Text
qry) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (n :: Nat) (m :: Nat) a b.
(KnownNat n, KnownNat m) =>
SearchEnv n a b
-> Text -> Text -> MatcherSized m a -> IO (Maybe Text)
matcherLoop SearchEnv n a b
env Text
qry Text
prev MatcherSized n a
m

fuzzyFunctions :: CaseSensitivity -> SearchFunctions MatchPart b
fuzzyFunctions :: forall b. CaseSensitivity -> SearchFunctions MatchPart b
fuzzyFunctions CaseSensitivity
c = forall a b.
(Text -> Matcher a)
-> (forall (n :: Nat).
    KnownNat n =>
    MatcherSized n a -> Text -> Maybe (MatchFull n))
-> (forall (n :: Nat).
    KnownNat n =>
    (Bool -> Text -> b)
    -> MatcherSized n a -> Text -> Vector n Int -> [b])
-> SearchFunctions a b
SearchFunctions (CaseSensitivity -> Text -> Matcher MatchPart
fuzzyMatcher CaseSensitivity
c) forall (n :: Nat).
KnownNat n =>
MatcherSized n MatchPart -> Text -> Maybe (MatchFull n)
fuzzyMatchSized forall (n :: Nat) a.
KnownNat n =>
(Bool -> Text -> a)
-> MatcherSized n MatchPart -> Text -> Vector n Int -> [a]
fuzzyMatchPartsAs

orderlessFunctions :: CaseSensitivity -> SearchFunctions Int b
orderlessFunctions :: forall b. CaseSensitivity -> SearchFunctions Int b
orderlessFunctions CaseSensitivity
c = forall a b.
(Text -> Matcher a)
-> (forall (n :: Nat).
    KnownNat n =>
    MatcherSized n a -> Text -> Maybe (MatchFull n))
-> (forall (n :: Nat).
    KnownNat n =>
    (Bool -> Text -> b)
    -> MatcherSized n a -> Text -> Vector n Int -> [b])
-> SearchFunctions a b
SearchFunctions (CaseSensitivity -> Text -> Matcher Int
orderlessMatcher CaseSensitivity
c) forall (n :: Nat).
KnownNat n =>
MatcherSized n Int -> Text -> Maybe (MatchFull n)
orderlessMatchSized forall (n :: Nat) a.
KnownNat n =>
(Bool -> Text -> a)
-> MatcherSized n Int -> Text -> Vector n Int -> [a]
orderlessMatchPartsAs

{-# INLINABLE makeChunks #-}
makeChunks :: forall n. KnownNat n => V.Vector Text -> Chunks n
makeChunks :: forall (n :: Nat). KnownNat n => Vector Text -> Chunks n
makeChunks Vector Text
v = forall (n :: Nat). Vector (Vector n Text) -> Chunks n
Chunks forall a b. (a -> b) -> a -> b
$ forall a. Int -> (Int -> a) -> Vector a
V.generate Int
numchunks (forall (n :: Nat) a. Vector n a -> Vector n a
SV.force forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HasCallStack => Maybe a -> a
fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a. KnownNat n => Vector a -> Maybe (Vector n a)
SV.toSized forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Vector Text
chunk)
  where
    n :: Int
n = forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy :: Proxy n)
    (Int
numchunks , Int
remainder) = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (forall a. Num a => a -> a -> a
+ Int
1) (forall a. Num a => a -> a -> a
+ Int
1) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Integral a => a -> a -> (a, a)
divMod (forall (t :: * -> *) a. Foldable t => t a -> Int
length Vector Text
v forall a. Num a => a -> a -> a
- Int
1) forall a b. (a -> b) -> a -> b
$ Int
n
    chunk :: Int -> Vector Text
chunk Int
i
      | Int
i forall a. Num a => a -> a -> a
+ Int
1 forall a. Ord a => a -> a -> Bool
< Int
numchunks  = forall a. Int -> Int -> Vector a -> Vector a
V.slice (Int
iforall a. Num a => a -> a -> a
*Int
n) Int
n Vector Text
v
      | Bool
otherwise          = forall a. Int -> Int -> Vector a -> Vector a
V.slice (Int
iforall a. Num a => a -> a -> a
*Int
n) Int
remainder Vector Text
v forall a. Semigroup a => a -> a -> a
<> forall a. Int -> a -> Vector a
V.replicate (Int
n forall a. Num a => a -> a -> a
- Int
remainder) Text
""

{-# INLINE makeChunksP #-}
makeChunksP :: KnownNat n => Proxy n -> V.Vector Text -> Chunks n
makeChunksP :: forall (n :: Nat). KnownNat n => Proxy n -> Vector Text -> Chunks n
makeChunksP Proxy n
_ = forall (n :: Nat). KnownNat n => Vector Text -> Chunks n
makeChunks

{-# INLINEABLE setToVectorST #-}
setToVectorST :: (a -> b) -> DS.Set a -> ST s (V.Vector b)
setToVectorST :: forall a b s. (a -> b) -> Set a -> ST s (Vector b)
setToVectorST a -> b
f Set a
s = MVector s b -> ST s (Vector b)
go forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *) a.
PrimMonad m =>
Int -> m (MVector (PrimState m) a)
MV.unsafeNew (forall a. Set a -> Int
DS.size Set a
s)
  where
    go :: MVector s b -> ST s (Vector b)
go MVector s b
mv = forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m ()
foldM_ (\Int
i a
e -> forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
MV.unsafeWrite MVector s b
mv Int
i (a -> b
f a
e) forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Int
i forall a. Num a => a -> a -> a
+ Int
1) Int
0 Set a
s forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
V.unsafeFreeze MVector s b
mv

startSearcher :: KnownNat n => SearchEnv n a b -> IO ()
startSearcher :: forall (n :: Nat) a b. KnownNat n => SearchEnv n a b -> IO ()
startSearcher = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO () -> IO ThreadId
forkIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a b. KnownNat n => SearchEnv n a b -> IO ()
searchLoop

sendQuery :: KnownNat n => SearchEnv n a b -> Text -> IO ()
sendQuery :: forall (n :: Nat) a b.
KnownNat n =>
SearchEnv n a b -> Text -> IO ()
sendQuery SearchEnv n a b
env = forall a. MVar a -> a -> IO ()
putMVar (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) (MVar (Maybe Text))
query) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just

stopSearcher :: KnownNat n => SearchEnv n a b -> IO ()
stopSearcher :: forall (n :: Nat) a b. KnownNat n => SearchEnv n a b -> IO ()
stopSearcher SearchEnv n a b
env = forall a. MVar a -> a -> IO ()
putMVar (SearchEnv n a b
env forall s a. s -> Getting a s a -> a
^. forall (n :: Nat) a b. Lens' (SearchEnv n a b) (MVar (Maybe Text))
query) forall a. Maybe a
Nothing

concatChunks :: KnownNat n => Int -> Chunks n -> V.Vector Text
concatChunks :: forall (n :: Nat). KnownNat n => Int -> Chunks n -> Vector Text
concatChunks Int
i (Chunks Vector (Vector n Text)
c) =  forall a b. (a -> Vector b) -> Vector a -> Vector b
V.concatMap forall (n :: Nat) a. Vector n a -> Vector a
SV.fromSized forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> Vector a -> Vector a
V.take Int
i forall a b. (a -> b) -> a -> b
$ Vector (Vector n Text)
c

forceChunks :: KnownNat n => Chunks n -> Chunks n
forceChunks :: forall (n :: Nat). KnownNat n => Chunks n -> Chunks n
forceChunks (Chunks Vector (Vector n Text)
v) = forall (n :: Nat). Vector (Vector n Text) -> Chunks n
Chunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> Vector a
V.force forall a b. (a -> b) -> a -> b
$ Vector (Vector n Text)
v

chunksFromStream :: forall n. KnownNat n => I.InputStream Text -> IO (Chunks n)
chunksFromStream :: forall (n :: Nat). KnownNat n => InputStream Text -> IO (Chunks n)
chunksFromStream InputStream Text
i = forall (n :: Nat). Vector (Vector n Text) -> Chunks n
Chunks forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (v :: * -> *) a. Vector v a => InputStream a -> IO (v a)
I.toVector forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a b. (a -> Maybe b) -> InputStream a -> IO (InputStream b)
I.mapMaybe (\Vector Text
v -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map forall (n :: Nat) a. Vector n a -> Vector n a
SV.force forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a. KnownNat n => Vector a -> Maybe (Vector n a)
SV.toSized forall a b. (a -> b) -> a -> b
$ Vector Text
v forall a. Vector a -> Vector a -> Vector a
V.++ forall a. Int -> a -> Vector a
V.replicate (Int
n forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length Vector Text
v) Text
"") forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (v :: * -> *) a.
Vector v a =>
Int -> InputStream a -> IO (InputStream (v a))
I.chunkVector Int
n InputStream Text
i)
  where
    n :: Int
n = forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall {k} (t :: k). Proxy t
Proxy :: Proxy n)

{-# INLINE chunksFromStreamP #-}
chunksFromStreamP :: forall n. KnownNat n => Proxy n -> I.InputStream Text -> IO (Chunks n)
chunksFromStreamP :: forall (n :: Nat).
KnownNat n =>
Proxy n -> InputStream Text -> IO (Chunks n)
chunksFromStreamP Proxy n
_ = forall (n :: Nat). KnownNat n => InputStream Text -> IO (Chunks n)
chunksFromStream

{-# INLINABLE chunksFromHandle #-}
chunksFromHandle :: KnownNat n => Proxy n -> Handle -> IO (Chunks n)
chunksFromHandle :: forall (n :: Nat). KnownNat n => Proxy n -> Handle -> IO (Chunks n)
chunksFromHandle Proxy n
p = forall (n :: Nat).
KnownNat n =>
Proxy n -> InputStream Text -> IO (Chunks n)
chunksFromStreamP Proxy n
p forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream ByteString -> IO (InputStream Text)
I.decodeUtf8 forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream ByteString -> IO (InputStream ByteString)
I.lines forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Handle -> IO (InputStream ByteString)
I.handleToInputStream

readVectorHandleWith :: (Text -> Text) -- ^ The function to transform the candidates.
  -> (V.Vector Text -> V.Vector Text) -- ^ The function to apply to the constructed vector before compacting.
  -> Handle -- ^ The handle to read from
  -> IO (V.Vector Text)
readVectorHandleWith :: (Text -> Text)
-> (Vector Text -> Vector Text) -> Handle -> IO (Vector Text)
readVectorHandleWith Text -> Text
f Vector Text -> Vector Text
t = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map Vector Text -> Vector Text
t forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. Vector v a => InputStream a -> IO (v a)
I.toVector forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a b. (a -> b) -> InputStream a -> IO (InputStream b)
I.map Text -> Text
f forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream ByteString -> IO (InputStream Text)
I.decodeUtf8 forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< InputStream ByteString -> IO (InputStream ByteString)
I.lines forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Handle -> IO (InputStream ByteString)
I.handleToInputStream

fileNamesSorted :: Handle -> IO (V.Vector Text)
fileNamesSorted :: Handle -> IO (Vector Text)
fileNamesSorted = (Text -> Text)
-> (Vector Text -> Vector Text) -> Handle -> IO (Vector Text)
readVectorHandleWith ((Char -> Bool) -> Text -> Text
T.takeWhileEnd (forall a. Eq a => a -> a -> Bool
/= Char
'/')) (forall a. Eq a => Vector a -> Vector a
V.uniq forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
(forall s. MVector s a -> ST s ()) -> Vector a -> Vector a
V.modify forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e, Ord e) =>
v (PrimState m) e -> m ()
sort)