@@ -20,7 +20,7 @@ import Data.Foldable (asum)
2020import Data.Functor (($>))
2121import Data.Maybe (fromMaybe)
2222import System.Random (randomRIO)
23−import Prelude hiding (any, all, take, sequence, sequenceA, takeWhile)
23+import Prelude hiding (any, all, take, sequence, sequenceA, takeWhile, span)
2424
2525import qualified Data.Traversable as TR
2626import qualified Data.Foldable as F
@@ -174,6 +174,37 @@ longestAllAny value =
174174 (drainWhile (<= value))
175175 )
176176
177+-------------------------------------------------------------------------------
178+-- Derived parsers
179+-------------------------------------------------------------------------------
180+
181+{-# INLINE span #-}
182+span :: MonadThrow m => Int -> SerialT m Int -> m ((), ())
183+span value = IP.parseD (span_ (<= (value `div` 2)) FL.drain FL.drain)
184+
185+ where
186+
187+ span_ p f1 f2 = PR.splitWith (,) (PR.takeWhile p f1) (PR.fromFold f2)
188+
189+{-# INLINE spanBy #-}
190+spanBy :: MonadThrow m => Int -> SerialT m Int -> m ((), ())
191+spanBy value =
192+ IP.parseD (spanBy_ (\_ i -> i <= (value `div` 2)) FL.drain FL.drain)
193+
194+ where
195+
196+ spanBy_ c f1 f2 = PR.splitWith (,) (PR.groupBy c f1) (PR.fromFold f2)
197+
198+{-# INLINE spanByRolling #-}
199+spanByRolling :: MonadThrow m => Int -> SerialT m Int -> m ((), ())
200+spanByRolling value =
201+ IP.parseD (spanByRolling_ (\_ i -> i <= value `div` 2) FL.drain FL.drain)
202+
203+ where
204+
205+ spanByRolling_ c f1 f2 =
206+ PR.splitWith (,) (PR.groupByRolling c f1) (PR.fromFold f2)
207+
177208-------------------------------------------------------------------------------
178209-- Parsers in which -fspec-constr-recursive=16 is problematic
179210-------------------------------------------------------------------------------
@@ -241,6 +272,13 @@ o_1_space_serial value =
241272 , benchIOSink value "longest (all,any)" $ longestAllAny value
242273 ]
243274
275+o_1_space_serial_derived :: Int -> [Benchmark]
276+o_1_space_serial_derived value =
277+ [ benchIOSink value "span" $ span value
278+ , benchIOSink value "spanBy" $ spanBy value
279+ , benchIOSink value "spanByRolling" $ spanByRolling value
280+ ]
281+
244282o_n_heap_serial :: Int -> [Benchmark]
245283o_n_heap_serial value =
246284 [
@@ -275,6 +313,7 @@ main = do
275313
276314 allBenchmarks value =
277315 [ bgroup (o_1_space_prefix moduleName) (o_1_space_serial value)
316+ , bgroup (o_1_space_prefix moduleName) (o_1_space_serial_derived value)
278317 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
279318 , bgroup (o_n_space_prefix moduleName) (o_n_space_serial value)
280319 ]