
Sorry :-). I am using Hugs, anything I did wrong ?
------------------------------------------------------------------------------------------------
newtype Parser a = P { parse :: (String -> [(a,String)]) }
instance Monad Parser where
return v = P (\s -> [(v,s)])
p >>= f = P (\s -> case parse p s of
[] -> []
[(v,str)] -> parse (f v) str)
fail _ = P (\_ -> [])
item :: Parser Char
item = Parser (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
p :: Parser (Char,Char)
p = do { x <- item
; item
; y <- item
; return (x,y) }
--------------------------------------------------
Prelude> :load c:\b.hs
[1 of 1] Compiling Main ( C:\b.hs, interpreted )
C:\b.hs:12:7: Not in scope: data constructor `Parser'
Failed, modules loaded: none.
Prelude>
在 2010年3月19日 下午6:01,Stephen Tetley
2010/3/19 国平张
: Sorry. The same error, This is new stuff.
Ah indeed - I didn't spot that one as I only read the code rather than ran it.
With the change the parser type to use /newtype/ all the primitive parsers have to be encoded inside the newtype's constructor (primitive parsers being ones that have to look directly at the input stream).
item :: Parser Char item = Parser $ \inp -> case inp of [] -> [] (x:xs) -> [(x,xs)]
Or in a more prosaic style
item :: Parser Char item = Parser (\inp -> case inp of [] -> [] (x:xs) -> [(x,xs)])
This is slightly tiresome. Fortunately once you have defined a small set of primitive parsers, many more parsers can be "derived" by combining the primitives rather than looking at the input stream - this is the power of the monadic style. The p parser you defined with the do ... notation is one such derived parser.
Best wishes
Stephen