on master help sign in
Add docs and asserts for fromParserK

Added a Control.Exception module providing "assert" and "verify" convenience utilities.

commiteff325538e19483ac88a31da518fc7a28f13ded2 authorHarendra Kumar <harendra@composewell.com> dateWed 2 Sep 2020, 09:05 (6 years ago) parentc3dcabc
3 files changed+61−1
src/Streamly/Internal/Control/Exception.hs+50 src/Streamly/Internal/Data/Parser/ParserK/Types.hs+10−1 streamly.cabal+1
src/Streamly/Internal/Control/Exception.hsnew file+50
@@ -0,0 +1,50 @@
1+-- |
2+-- Module : Streamly.Internal.Control.Exception
3+-- Copyright : (c) 2019 Composewell Technologies
4+--
5+-- License : BSD3
6+-- Maintainer : streamly@composewell.com
7+-- Stability : experimental
8+-- Portability : GHC
9+--
10+-- Additional "Control.Exception" utilities.
11+
12+module Streamly.Internal.Control.Exception
13+ ( assertM
14+ , verify
15+ , verifyM
16+ )
17+where
18+
19+import Control.Exception (assert)
20+
21+-- Like 'assert' but returns @()@ in an 'Applicative' context so that it can be
22+-- used as an independent statement in a @do@ block.
23+--
24+-- /Internal/
25+--
26+{-# INLINE assertM #-}
27+assertM :: Applicative f => Bool -> f ()
28+assertM predicate = assert predicate (pure ())
29+
30+-- | Like 'assert' but is not removed by the compiler, it is always present in
31+-- production code.
32+--
33+-- /Internal/
34+--
35+{-# INLINE verify #-}
36+verify :: Bool -> a -> a
37+verify predicate val =
38+ if predicate
39+ -- XXX it would be nice if we can print the predicate expr.
40+ then error "verify failed"
41+ else val
42+
43+-- Like 'verify' but returns @()@ in an 'Applicative' context so that it can be
44+-- used as an independent statement in a @do@ block.
45+--
46+-- /Internal/
47+--
48+{-# INLINE verifyM #-}
49+verifyM :: Applicative f => Bool -> f ()
50+verifyM predicate = verify predicate (pure ())
src/Streamly/Internal/Data/Parser/ParserK/Types.hs+10−1
@@ -40,6 +40,7 @@ import qualified Control.Monad.Fail as Fail
4040#if !(MIN_VERSION_base(4,10,0))
4141import Data.Semigroup ((<>))
4242#endif
43+import Streamly.Internal.Control.Exception
4344
4445import qualified Streamly.Internal.Data.Parser.ParserD.Types as D
4546
@@ -205,6 +206,9 @@ data FromParserK b e c = FPKDone !Int !b | FPKError !e | FPKCont c
205206
206207-- | Convert a CPS style 'Parser' to a direct style 'D.Parser'.
207208--
209+-- "initial" returns a continuation which can be called one input at a time
210+-- using the "step" function.
211+--
208212-- /Internal/
209213--
210214{-# INLINE_LATE fromParserK #-}
@@ -221,7 +225,12 @@ fromParserK parser = D.Parser step initial extract
221225 Partial _ cont -> FPKCont cont -- XXX can we get this?
222226 Continue _ cont -> FPKCont cont
223227
224− step (FPKDone n b) _ = return $ D.Done (n + 1) b
228+ -- Note, we can only reach FPKDone and FPKError from "initial". FPKCont
229+ -- always transitions to only FPKCont. The input remains unconsumed in
230+ -- this case so we use "n + 1".
231+ step (FPKDone n b) _ = do
232+ assertM (n == 0)
233+ return $ D.Done (n + 1) b
225234 step (FPKError e) _ = return $ D.Error e
226235 step (FPKCont cont) a = do
227236 r <- cont (Just a)
streamly.cabal+1
@@ -383,6 +383,7 @@ library
383383
384384 -- Internal modules
385385 , Streamly.Internal.BaseCompat
386+ , Streamly.Internal.Control.Exception
386387 , Streamly.Internal.Control.Monad
387388 , Streamly.Internal.Data.Tuple.Strict
388389 , Streamly.Internal.Data.Maybe.Strict