Combinators should be more strict
- Dominant language
- Haskell
- Stars
- 531
- Forks
- 98
- PR merge metrics
- No merged PRs in 30d
Description
I found and fixed lots of small space leaks in cassava but rewriting several of the combinators like so:
``` haskell
-- | Specialized version of 'sepBy1'' which is faster due to not
-- accepting an arbitrary separator.
sepByDelim1' :: AL.Parser a
-> Word8 -- ^ Field delimiter
-> AL.Parser [a]
sepByDelim1' p !delim = liftM2' (:) p loop
where
loop = do
mb <- A.peekWord8
case mb of
Just b | b == delim -> liftM2' (:) (A.anyWord8 *> p) loop
_ -> pure []
{-# INLINE sepByDelim1' #-}
```
(Ignore the use of `peekWord8` instead of `<|>`, that's an optimization specific to my case.)
Note the use of `liftM2'` instead of `(:) <$> (A.anyWord8 *> p) <*> loop`. Without `liftM2'` we're building up a thunk in the list. This thunk will always be evaluated when we eventually run the parser so creating it here is unnecessary and wastes space. I would guess that (almost) all uses of `<$>` and `<*>` should be replaced by strict versions.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.