After reading LYAH's Chapter 08 and SO questions (1, 2) about Real World Haskell's Parse
definition:
newtype Parse a = Parse {
runParse :: ParseState -> Either String (a, ParseState) }
For me, now I think it is a key understanding how runParse
is evaluated when runParse
is viewed as a function.
(1) ghci> :t runParse
will get
runParse :: Parse a -> ParseState -> Either String (a, ParseState)
(2) For trying runParse
, similar to RWH's The identity Parser
, I used the following example:
ghci> runParse (Parse (\s -> Right (1,s))) (ParseState (L8.pack "") 0)
I got the result:
Right (1,ParseState {string = "", offset = 0})
I can guess that the above evaluation is that (Parse (\s -> Right (1,s)))
and (ParseState (L8.pack "") 0)
first are parameters of runParse
and anonymous function (\s -> Right (1, s))
uses (ParseState (L8.pack "") 0)
as its parameter . But this guess makes me confused:
Why (ParseState (L8.pack "") 0)
is used as (\s -> Right (1, s))
's parameter during evaluating? How does the whole runParse
eval finish?
Also, I can write an alternative function for a simple definition, such as in LYAH:
newtype CharList = CharList {getCharList :: [Char]}
For this, CharList
and getCharList
can be defined as:
newtype CharList = CharList [Char]
getCharList :: CharList -> [Char]
getCharList cl = case cl of
CharList x -> x
So, in the first definition for CharList
, it is sure that there exists a pattern match. If I can implement a explicit function with pattern match like this for the previous runParse
I will understand it. But I don't know how to do it?