- p >>= f = Parser $ do saved@(_, isEOFFatal) <- get -- 失敗した時の爲に状態を保存
- result <- runParser p
- case result of
- Success a -> runParser (f a)
- IllegalInput -> do put saved -- 状態を復歸
- return IllegalInput
- ReachedEOF -> do unless isEOFFatal
- $ put saved -- 状態を復歸
- return ReachedEOF
- return = Parser . return . Success
- fail _ = Parser $ return IllegalInput
-
--- |@'parse' p bstr@ parses @bstr@ with @p@ and returns @(result,
--- remaining)@.
-parse :: Parser a -> ByteString -> (ParserResult a, ByteString)
-parse p input = let (result, (input', _)) = runState (runParser p) (input, True)
- in
- (result, input')
+ p >>= f = Parser $! do saved <- get -- 失敗した時の爲に状態を保存
+ result <- runParser p
+ case result of
+ Success a -> runParser (f a)
+ IllegalInput -> do put saved -- 状態を復歸
+ return IllegalInput
+ ReachedEOF -> do put saved -- 状態を復歸
+ return ReachedEOF
+ return x = x `seq` Parser $! return $! Success x
+ fail _ = Parser $! return $! IllegalInput
+
+-- |@'failP'@ is just a synonym for @'Prelude.fail'
+-- 'Prelude.undefined'@.
+failP :: Parser a
+failP = fail undefined
+
+-- |@'parse' p bstr@ parses @bstr@ with @p@ and returns @(# result,
+-- remaining #)@.
+parse :: Parser a -> Lazy.ByteString -> (# ParserResult a, Lazy.ByteString #)
+parse p input -- input は lazy である必要有り。
+ = p `seq`
+ let (result, state') = runState (runParser p) (PST input True)
+ in
+ result `seq` (# result, pstInput state' #) -- pstInput state' も lazy である必要有り。