问题
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?
回答1:
After several hours, I think I can answer this myself.
Because runParse
is a function with two parameters:
runParse :: Parse a -> ParseState -> Either String (a, ParseState)
After reviewing Partial Function Application principal
RWH descriped : In Haskell, all functions take only one argument.
I know that
ghci> runParse (Parse (\s -> Right (1,s))) (ParseState (L8.pack "") 0)
and :
ghci> let y = runParse (Parse (\s -> Right (1,s)))
ghci> y (ParseState (L8.pack "") 0)
are the same, and in ghci
this evaluation must be divided into two steps:
(1) evaluating the function runParse
with a parameter Parse a
, which returns a function with a parameter with type ParseState
, if Parse a
is (Parse (\s -> Right (1,s)))
, according to the simplest example in LYAH:
ghci> newtype CharList = CharList {getCharList :: [Char]}
ghci> getCharList (CharList "ab")
"ab"
so the result of executing
runParse (Parse (\s -> Right (1,s)))
is (\s -> Right (1,s))
, and it is verified from the fact: the type of ghci> :t runParse (Parse (\s -> Right (1,s)))
is
runParse (Parse (\s -> Right (1,s))) :: Num a => ParseState -> Either String (a, ParseState)
(2) after difficult step (1) for me, I get a function called y
in this case, which needs a parameter with a type ParseState
, y (ParseState (L8.pack "") 0)
will get a predicated result:
Right (1,ParseState {string = "", offset = 0})
I need keep it in mind that , for a function with more than one parameters, either you give all parameters one time or you give one parameter one time, the function's evaluation flow always includes the same amount as the number of parameters of steps and every step evaluates a function with one parameter.
来源:https://stackoverflow.com/questions/26696064/how-does-the-function-embeded-in-runparse-of-rwh-get-parameter-with-type-parsest