What is being passed in?
In the code:
oneChar :: Char -> Doc
oneChar c = case lookup c simpleEscapes of
Just r -> text r
Nothing | mustEscape c -> hexEscape c
| otherwise -> char c
where mustEscape c = c < ' ' || c == '\x7f' || c > '\xff'
simpleEscapes :: [(Char, Str开发者_开发技巧ing)]
simpleEscapes = zipWith ch "\b\n\f\r\t\\\"/" "bnfrt\\\"/"
where ch a b = (a, ['\\',b])
r isn't being passed to oneChar. Where does r come from?
lookup c simpleEscapes
returns a Maybe String
value, which can be either Nothing
or Just <a string>
. r
is the string contained in the Just
, as defined by the line:
Just r -> text r
The case keyword introduces a pattern match, which has the form case EXPR of (PATTERN -> EXPR)+
. So Just r
is a pattern, that matches the result of lookup c simpleEscapes of
. In a pattern, variables can be bound. Basically this means, if lookup c simpleEscapes of
returns a Just
then r
will be bound to the value inside that Just
and the result of the expression will be text r
.
If you're asking where the identifier is introduced, it's bound by the pattern match in the case
statement, the same way the identifier c
is bound by the pattern match in the function definition.
Any pattern match can introduce a new identifier for the associated expression:
(\(Just x) -> x) foo
let (Just x) = foo in x
f (Just x) = x
case foo of
Just x -> x
...all of those introduce a new identifier named x
. In fact, they're all pretty much equivalent, because the compiler converts all of them into case
blocks under the hood.
You're using a case statement on the value returned by lookup c simpleEscapes, which is of type Maybe. Maybe has two data constructors: Just and Nothing. The Just data constructor is parameterized by one value, the Nothing data constructor has no parameters.
So in this case, r is the formal parameter to the Just data constructor: its the actual value in the returned value from lookup.
精彩评论