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?
runParsesimple retrieves a value from a record.runParse (Parse (\s -> Right (1,s)))is exactly equal to\s -> Right (1,s). After that, it is just regular function application.