New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Data.Parser.ParserD.deintercalate #843
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -771,15 +771,21 @@ lookAhead p = K.toParserK $ D.lookAhead $ K.fromParserK p | |||||||||||||||||||
-- | ||||||||||||||||||||
-- This undoes a "gintercalate" of two streams. | ||||||||||||||||||||
-- | ||||||||||||||||||||
-- /Unimplemented/ | ||||||||||||||||||||
-- /Internal/ | ||||||||||||||||||||
-- | ||||||||||||||||||||
{-# INLINE deintercalate #-} | ||||||||||||||||||||
deintercalate :: | ||||||||||||||||||||
-- Monad m => | ||||||||||||||||||||
MonadCatch m => | ||||||||||||||||||||
Fold m a y -> Parser m x a | ||||||||||||||||||||
-> Fold m b z -> Parser m x b | ||||||||||||||||||||
-> Parser m x (y, z) | ||||||||||||||||||||
deintercalate = undefined | ||||||||||||||||||||
deintercalate fld1 prsr1 fld2 prsr2 = | ||||||||||||||||||||
K.toParserK $ | ||||||||||||||||||||
D.deintercalate | ||||||||||||||||||||
fld1 | ||||||||||||||||||||
(K.fromParserK prsr1) | ||||||||||||||||||||
fld2 | ||||||||||||||||||||
(K.fromParserK prsr2) | ||||||||||||||||||||
Comment on lines
+782
to
+788
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||
|
||||||||||||||||||||
------------------------------------------------------------------------------- | ||||||||||||||||||||
-- Sequential Collection | ||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -154,7 +154,7 @@ module Streamly.Internal.Data.Parser.ParserD | |
where | ||
|
||
import Control.Exception (assert) | ||
import Control.Monad.Catch (MonadCatch, MonadThrow(..)) | ||
import Control.Monad.Catch (MonadCatch, MonadThrow(..), catchAll) | ||
import Streamly.Internal.Data.Fold.Types (Fold(..)) | ||
import Streamly.Internal.Data.Tuple.Strict (Tuple'(..)) | ||
|
||
|
@@ -646,18 +646,135 @@ lookAhead (Parser step1 initial1 _) = Parser step initial extract | |
------------------------------------------------------------------------------- | ||
-- Interleaving | ||
------------------------------------------------------------------------------- | ||
|
||
data ParserTurn = Parser1 | Parser2 | ||
|
||
-- | ||
-- | See 'Streamly.Internal.Data.Parser.deintercalate'. | ||
-- | ||
-- /Unimplemented/ | ||
-- /Internal/ | ||
-- | ||
{-# INLINE deintercalate #-} | ||
deintercalate :: | ||
-- Monad m => | ||
MonadCatch m => | ||
Fold m a y -> Parser m x a | ||
-> Fold m b z -> Parser m x b | ||
-> Parser m x (y, z) | ||
deintercalate = undefined | ||
deintercalate | ||
(Fold fstep1 finitial1 fextract1) | ||
(Parser pstep1 pinitial1 pextract1) | ||
(Fold fstep2 finitial2 fextract2) | ||
(Parser pstep2 pinitial2 pextract2) = | ||
|
||
Parser step initial extract | ||
|
||
where | ||
|
||
initial = do | ||
finit1 <- finitial1 | ||
pinit1 <- pinitial1 | ||
finit2 <- finitial2 | ||
pinit2 <- pinitial2 | ||
return (finit1, pinit1, finit2, pinit2, Parser1, 0::Int) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Depending on the benchmarks, you might want to use a strict state, |
||
|
||
step (fs1, ps1, fs2, ps2, currentParser, numBuffered) a = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of |
||
case currentParser of | ||
Parser1 -> do | ||
st <- pstep1 ps1 a | ||
case st of | ||
Partial n ps1new -> | ||
return $ Partial n (fs1, ps1new, fs2, ps2, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put the tuple on the same line? |
||
currentParser, 0) | ||
Continue n ps1new -> do | ||
let | ||
newNumBuffered = | ||
if n==0 | ||
then numBuffered + 1 | ||
else numBuffered - n | ||
Comment on lines
+689
to
+693
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If |
||
return $ Continue n (fs1, ps1new, fs2, ps2, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put the tuple on the same line? |
||
currentParser, newNumBuffered) | ||
Done n result -> do | ||
res1 <- fstep1 fs1 result | ||
pinit1 <- pinitial1 | ||
pinit2 <- pinitial2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there are multiple unrequired initializations here. |
||
case res1 of | ||
FL.Partial fs1new -> | ||
return $ Partial n (fs1new, pinit1, fs2, pinit2, | ||
Parser2, numBuffered) | ||
FL.Done result1 -> do | ||
result2 <- fextract2 fs2 | ||
return $ Done numBuffered (result1, result2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should just backtrack |
||
Error _ -> do | ||
-- input definitively rejected by the first parser | ||
pinit1 <- pinitial1 | ||
pinit2 <- pinitial2 | ||
return $ Partial numBuffered (fs1, pinit1, fs2, pinit2, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should backtrack |
||
Parser2, numBuffered-1) | ||
-- return $ Done numBuffered (result1, result2) | ||
|
||
Parser2 -> do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comments made above apply to this branch. |
||
st <- pstep2 ps2 a | ||
case st of | ||
Partial n ps2new -> | ||
return $ Partial n (fs1, ps1, fs2, ps2new, | ||
currentParser, 0) | ||
Continue n ps2new -> do | ||
let | ||
newNumBuffered = | ||
if n==0 | ||
then numBuffered + 1 | ||
else numBuffered - n | ||
return $ Continue n (fs1, ps1, fs2, ps2new, | ||
currentParser, newNumBuffered) | ||
Done n result -> do | ||
res2 <- fstep2 fs2 result | ||
pinit1 <- pinitial1 | ||
pinit2 <- pinitial2 | ||
case res2 of | ||
FL.Partial fs2new -> | ||
return $ Partial n (fs1, pinit1, fs2new, pinit2, | ||
Parser1, numBuffered) | ||
FL.Done result2 -> do | ||
result1 <- fextract1 fs1 | ||
return $ Done numBuffered (result1, result2) | ||
Error _ -> do | ||
-- input definitively rejected by the second parser | ||
pinit1 <- pinitial1 | ||
pinit2 <- pinitial2 | ||
return $ Partial numBuffered (fs1, pinit1, fs2, pinit2, | ||
Parser2, numBuffered-1) | ||
-- return $ Done numBuffered (result1, result2) | ||
|
||
|
||
|
||
extract (fs1, ps1, fs2, ps2, currentParser, _) = | ||
case currentParser of | ||
Parser1 -> do | ||
maybeRes <- catchAll | ||
(fmap Just $ pextract1 ps1) | ||
(\_ -> return Nothing) | ||
result1 <- case maybeRes of | ||
Nothing -> fextract1 fs1 | ||
Just res -> do | ||
fs1new <- fstep1 fs1 res | ||
case fs1new of | ||
FL.Done result1' -> return result1' | ||
FL.Partial fs1new' -> fextract1 fs1new' | ||
result2 <- fextract2 fs2 | ||
return (result1, result2) | ||
Parser2 -> do | ||
maybeRes <- catchAll | ||
(fmap Just $ pextract2 ps2) | ||
(\_ -> return Nothing) | ||
result2 <- case maybeRes of | ||
Nothing -> fextract2 fs2 | ||
Just res -> do | ||
fs2new <- fstep2 fs2 res | ||
case fs2new of | ||
FL.Done result2' -> return result2' | ||
FL.Partial fs2new' -> fextract2 fs2new' | ||
result1 <- fextract1 fs1 | ||
return (result1, result2) | ||
|
||
------------------------------------------------------------------------------- | ||
-- Sequential Collection | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -178,6 +178,32 @@ takeBetween = | |
else property False | ||
Left _ -> property (m > n || list_length < m) | ||
|
||
-- deintercalate :: Property | ||
-- deintercalate = | ||
-- forAll (chooseInt (min_value, max_value)) $ \n -> | ||
-- forAll (listOf (chooseInt (min_value, max_value))) $ \ls -> | ||
-- case S.parseD (P.deintercalate FL.drain (P.satisfy odd) FL.drain | ||
-- (P.satisfy even)) (S.fromList ls) of | ||
-- Right parsed_list -> property (length ls == length parsed_list) | ||
-- Left _ -> property False | ||
|
||
deintercalate :: Property | ||
deintercalate = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is being tested in |
||
forAll (listOf (chooseInt (0, 1))) $ \ls -> | ||
case S.parseD prsr (S.fromList ls) of | ||
Right parsed_list_tuple -> | ||
parsed_list_tuple == List.partition (== 0) ls | ||
Left _ -> False | ||
|
||
where | ||
prsr = P.deintercalate concatFold prsr_1 concatFold prsr_2 | ||
prsr_1 = P.takeWhile (== 0) FL.toList | ||
prsr_2 = P.takeWhile (== 1) FL.toList | ||
concatFold = FL.Fold | ||
(\concatList curr_list -> | ||
return $ FL.Partial $ concatList ++ curr_list) | ||
(return []) return | ||
|
||
take :: Property | ||
take = | ||
forAll (chooseInt (min_value, max_value)) $ \n -> | ||
|
@@ -696,6 +722,7 @@ main = | |
takeBetweenPass | ||
prop "P.takeBetween m n = Prelude.take when len >= m and len <= n and\ | ||
\fail otherwise" takeBetween | ||
prop "P.deintercalate test" deintercalate | ||
prop "P.take = Prelude.take" Main.take | ||
prop "P.takeEQ = Prelude.take when len >= n" takeEQPass | ||
prop "P.takeEQ = Prelude.take when len >= n and fail otherwise" Main.takeEQ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need benchmarks for
ParserD
as well.