{-# LANGUAGE BangPatterns #-} module Tests.SlowFunctions ( indices , splitOn ) where import qualified Data.Text as T import Data.Text.Internal (Text(..)) import Data.Text.Unsafe (iter_, unsafeHead, unsafeTail) indices :: T.Text -- ^ Substring to search for (@needle@) -> T.Text -- ^ Text to search in (@haystack@) -> [Int] indices needle@(Text _narr _noff nlen) haystack@(Text harr hoff hlen) | T.null needle = [] | otherwise = scan 0 where scan i | i >= hlen = [] | needle `T.isPrefixOf` t = i : scan (i+nlen) | otherwise = scan (i+d) where t = Text harr (hoff+i) (hlen-i) d = iter_ haystack i splitOn :: T.Text -- ^ Text to split on -> T.Text -- ^ Input text -> [T.Text] splitOn pat src0 | T.null pat = error "splitOn: empty" | l == 1 = T.split (== (unsafeHead pat)) src0 | otherwise = go src0 where l = T.length pat go src = search 0 src where search !n !s | T.null s = [src] -- not found | pat `T.isPrefixOf` s = T.take n src : go (T.drop l s) | otherwise = search (n+1) (unsafeTail s)