haskell / haskell/attoparsec

Combinators should be more strict

Open
#109 1 comment 0 reactions 0 assignees View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.