I look at this declaration:
newtype Parser a = Parser { parse :: String -> Maybe (a,String) }
Here is what I understand:
1) Parser is declared as a type with a type parameter a
2) You can instantiate Parser by providing a parser function for example p = Parser (\s -> Nothing)
What I observed is that suddenly I have a function name parse
defined and it is capable of running Parsers.
For example, I can run:
parse (Parser (\s -> Nothing)) "my input"
and get Nothing
as output.
How was this parse function got defined with this specific signature? How does this function "know" to execute the Parser given to it? Hope that someone can clear my confusion.
Thanks!
When you write newtype Parser a = Parser { parse :: String -> Maybe (a,String) }
you introduce three things:
A type named Parser
.
A term level constructor of Parser
s named Parser
. The type of this function is
Parser :: (String -> Maybe (a, String)) -> Parser a
You give it a function and it wraps it inside a Parser
parse
to remove the Parser
wrapper and get your function back. The type of this function is:parse :: Parser a -> String -> Maybe (a, String)
Check yourself in ghci
:
Prelude> newtype Parser a = Parser { parse :: String -> Maybe (a,String) }
Prelude> :t Parser
Parser :: (String -> Maybe (a, String)) -> Parser a
Prelude> :t parse
parse :: Parser a -> String -> Maybe (a, String)
Prelude>
It's worth nothing that the term level constructor (Parser
) and the function to remove the wrapper (parse
) are both arbitrary names and don't need to match the type name. It's common for instance to write:
newtype Parser a = Parser { unParser :: String -> Maybe (a,String) }
this makes it clear unParse
removes the wrapper around the parsing function. However, I recommend your type and constructor have the same name when using newtypes
.
How does this function "know" to execute the Parser given to it
You are unwrapping the function using parse
and then calling the unwrapped function with "myInput"
.