hpaste

recent | annotate | new

{-# OPTIONS -fbang-patterns -O2 #-}

module Find where

import qualified Data.ByteString as  S
import Data.ByteString.Base

import Test.QuickCheck.Batch
import Test.QuickCheck
import Data.Word
import System.Random


findSubtring2 :: ByteString -> ByteString -> Maybe Int
findSubtring2 test big = go big 0
    where
        go !s !n | test `S.isPrefixOf` s = Just n
                 | S.null s              = Nothing
                 | otherwise             = go (unsafeTail s) (n+1)


prop_find s t = findSubtring2 s t == S.findSubstring s t
{-
*Find> quickCheck prop_find
OK, passed 100 tests.
-}

------------------------------------------------------------------------
-- testing

instance Arbitrary Word8 where
    arbitrary = choose (minBound, maxBound)
    coarbitrary c = variant (fromIntegral ((fromIntegral c) `rem` 4))

instance Random Word8 where
  randomR = integralRandomR
  random = randomR (minBound,maxBound)

instance Arbitrary S.ByteString where
  arbitrary = S.pack `fmap` arbitrary
  coarbitrary s = coarbitrary (S.unpack s)

integralRandomR :: (Integral a, RandomGen g) => (a,a) -> g -> (a,g)
integralRandomR  (a,b) g = case randomR (fromIntegral a :: Integer,
                                         fromIntegral b :: Integer) g of
                            (x,g) -> (fromIntegral x, g)

findSubtringLazy :: L.ByteString -> L.ByteString -> Maybe Int
findSubtringLazy !test !big = go big 0
    where
        go !s !n | test `L.isPrefixOf` s = Just n
                 | L.null s              = Nothing
                 | otherwise             = go (L.tail s) (n+1)