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)