1 {-# LANGUAGE BangPatterns #-}
    2 
    3 module SlowFunctions
    4     (
    5       indices
    6     , split
    7     ) where
    8 
    9 import qualified Data.Text as T
   10 import Data.Text.Internal (Text(..))
   11 import Data.Text.Unsafe (iter_, unsafeHead, unsafeTail)
   12 
   13 indices :: T.Text              -- ^ Substring to search for (@needle@)
   14         -> T.Text              -- ^ Text to search in (@haystack@)
   15         -> [Int]
   16 -- entered 300 timesindices needle@(Text _narr _noff nlen) haystack@(Text harr hoff hlen)
   17     | T.null needle = []
   18     | otherwise     = scan 0
   19   where
   20     scan i | i >= hlen = []
   21            | needle `T.isPrefixOf` t = i : scan (i+nlen)
   22            | otherwise = scan (i+d)
   23            where t = Text harr (hoff+i) (hlen-i)
   24                  d = iter_ haystack i
   25 
   26 split :: T.Text                 -- ^ Text to split on
   27       -> T.Text                 -- ^ Input text
   28       -> [T.Text]
   29 -- entered 100 timessplit pat src0
   30     | T.null pat  = error "split: empty"
   31     | l == 1      = T.splitBy (== (unsafeHead pat)) src0
   32     | otherwise   = go src0
   33   where
   34     l      = T.length pat
   35     go src = search 0 src
   36       where
   37         search !n !s
   38             | T.null s             = [src]      -- not found
   39             | pat `T.isPrefixOf` s = T.take n src : go (T.drop l s)
   40             | otherwise            = search (n+1) (unsafeTail s)