-
Notifications
You must be signed in to change notification settings - Fork 98
Alternative formulation of Stream #72
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
Comments
Folks use the m in uncons to allow "streams" that aren't fully in memory. E.g. Streaming from disk or pipes. |
Thanks @ekmett I have added the What you think on moving |
Also in |
Lots of people use different states that happen to run in the IO monad. |
I'm not sure about the Position -> f -> Maybe { head :: c, tail :: f, newPos :: Position } which would allow for different parsing based on position, and avoids capturing a very expensive closure. An example where that might matter is if your lexer prepass did something like c preprocessing where it might need to know if it is at the start of file to know how to properly handle finding # directives. Regardless, building a function there means that this will never fully unbox into something that just runs on the stack no matter what instance you work with unlike the existing solution. You're always paying full price. |
This is what i came to: class Stream s m t | s -> t where
uncons :: ParserState s -> m (Maybe (Tuple t (ParserState s)))
stripPrefix :: Prefix s -> ParserState s -> m (Maybe (ParserState s))
type ParserState s = { input :: s, pos :: Position } |
Poking at this from the other side: First You've now converged almost back to the existing design. The major difference is that Here you're bolting in machinery to update position, but 'uncons' doesn't need to inspect the char it gives back, so there is no "double dipping" on work, there. Only the "update position" combinator passed to So the common use-cases don't use the extra information you are supplying here to access the stream. This consciously leaves open the notion of what is a 'column' to At present It feels to me that this part of your design couples the stream to the notion of columns in a really tight way that then require more code duplication (copying the update position function into stream types that previously lived agnostic of parsec's rather awful Now Adding something like Here things become more nebulous as at this point you are looking at the characters given back and so my argument about how data Delta = Delta !Int !Int
instance Monoid Delta where
mempty = Delta 0 0
mappend (Delta a b) (Delta 0 d) = Delta a (b + d)
mappend (Delta a _) (Delta c d) = Delta (a + c) d Then convert With that in mind, it seems even |
Thanks for detailed response! I would need to think on this, meanwhile, where can I find definition of |
I wrote it inline above as an example. It isn't used by parsec. You can read Delta x y as 'move down x lines, and if x is > 1 the column is absolute, otherwise its relative. |
Here is what kind of Stream I came to independently, when I was playing with purescript-parsing:
purescript-contrib/purescript-parsing#62
I think this formulation is nicer as you don't need to carry updatePosition function around, and I don't see why you need the
m
inuncons
too.Would like your thoughts on this formulation.
The text was updated successfully, but these errors were encountered: