data ParseStepResult input result =
Success (Maybe (input -> ParseStepResult input result)) (Maybe result)
| Failure
(ie, parsers using stream combinators like Fudgets have that property)
ie, either a continuation of parsing process and result or failure flag.
2) How to write parser like one above that could be saved into database?
data ParserCont input result = ...
deriving (Show, Read)
data ParseStepResult input result =
Success (Maybe (ParserCont input result)) (Maybe result)
| Failure
I could imagine that it is possible using parser generator like Happy.
Is it possible to get right using parsing combinators library?
_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
I think you're looking for `iteratees'.
| newtype IterateeG c el m a
| = IterateeG {runIter :: StreamG c el -> m (IterGV c el m a)}
|
| data IterGV c el m a
| = Done a (StreamG c el) | Cont (IterateeG c el m a) (Maybe ErrMsg)
|
| data StreamG c el = EOF (Maybe ErrMsg) | Chunk (c el)
See
http://okmij.org/ftp/Streams.html
http://hackage.haskell.org/package/iteratee
See also
http://www.haskell.org/haskellwiki/Enumerator_and_iteratee
http://therning.org/magnus/archives/735/comment-page-1#comment-188128
http://comonad.com/reader/2009/iteratees-parsec-and-monoid/
http://inmachina.net/~jwlato/haskell/iter-audio/
--
vvv
I am looking more for the way to serialize intermediate parser
computations. The first problem is, actually, easy one. ;)
Probably you'll have to create a data constructor for each step
of your parser.
AFAIK, one of HAppS modules does a similar transformation via
Template Haskell. The functions specify transactions, and each
transaction is converted to a serializable data type. Then it's
possible to create a transaction log by serializing them before
their execution.
Of course you could also modify Happy instead of writing a TH
transformation. Both are preprocessor. TH would be more
convenient, though.
--
Felipe.
The happstack transaction serialization doesn't support higher-order
types. Whether or not that's too much of a restriction depends on what
you want your parsers to look like.
Antoine
Thank you very much.
I think, I will try Template Haskell approach, I prefer combinators
over the generators.
Higher-order like "data A m a = A (m a)"?
In that case, You'll be able to serialize that as long as you can
serialize (m a).
I meant higher-order as in function-types. So you wouldn't be able to serialize:
string :: String -> Parser String
Unless you had some way to reify the particular function to data.
I'm also hazy on how you could encode a fully monadic expression - n
applicative style parser may be a bit more modest.
Antoine
That's the idea, to create something like
data MyParser = FunString String
| ...
interpret :: MyParser -> Parser String
interpret (FunString str) = string str
However you're right in a sense, you can't use this scheme to
serialize any functions taking functions, like
something :: (a -> Parser a) -> a -> Parser a
because
data MyParser = FunSomething (a -> MyParser) a
wouldn't be serializable. Well, maybe if your parsers were
arrows... :)
--
Felipe.
A pair of problems:
1) How to write a parser that could be restarted? Like, it will be
represented by a function that returns something along the lines
data ParseStepResult input result =
Success (Maybe (input -> ParseStepResult input result)) (Maybe result)
| Failure
2) How to write parser like one above that could be saved into database?
data ParserCont input result = ...
deriving (Show, Read)
data ParseStepResult input result =
Success (Maybe (ParserCont input result)) (Maybe result)
| Failure
I could imagine that it is possible using parser generator like Happy.
Is it possible to get right using parsing combinators library?
However you're right in a sense, you can't use this scheme to
serialize any functions taking functions, like
something :: (a -> Parser a) -> a -> Parser a
because
data MyParser = FunSomething (a -> MyParser) a
wouldn't be serializable. Well, maybe if your parsers were
arrows... :)
Hmmm... but, assuming a preprocessor, you probably would be able
to transform this code:
number :: MyArrow String Int
number = ...
showMe :: MyArrow Int String
showMe = ...
doSomething :: Int -> Maybe Int
doSomething = ...
f = showMe . arr doSomething . number
...into this code:
data Action a b where
Number :: Action String Int
ShowMe :: Action Int String
ArrDoSomething :: Action Int (Maybe Int)
(:*:) :: Action b c -> Action a b -> Action a c
-- repeat definitions of number, showMe, doSomething
f = ShowMe :*: ArrDoSomething :*: Number
interpret :: Action a b -> MyArrow a b
interpret Number = number
interpret ShowMe = showMe
interpret ArrDoSomething = arr doSomething
interpret (f :*: g) = f . g
instance Binary (Action a b) where
put Number = putWord8 1
put ShowMe = putWord8 2
put ArrDoSomething = putWord8 3
put (f :*: g) = putWord8 4 >> put f >> put g
get = do i <- getWord8
case i of
1 -> return Number
2 -> return ShowMe
3 -> return ArrDoSomething
4 -> (:*:) <$> get <*> get
The only part missing here is being able to run only a small part
of the arrow's computation and then return another Action.
Is my example contrived? Am I missing something? :)
Thanks!
Hmmm... but, assuming a preprocessor, you probably would be able
to transform this code:
[snip]
The only part missing here is being able to run only a small part
of the arrow's computation and then return another Action.
Is my example contrived? Am I missing something? :)
Hehe, I see :). However I think this preprocessor would be
feasible without too much effort. It would only replace arrow
functions with data constructors, nothing really fancy. Well,
perhaps I'm wrong. ;)