-- file: ch16/HttpRequestParser.hs
p_request :: CharParser () HttpRequest
p_request = q "GET" Get (pure Nothing)
<|> q "POST" Post (Just <$> many anyChar)
where q name ctor body = liftM4 HttpRequest req url p_headers body
where req = ctor <$ string name <* char ' '
url = optional (char '/') *>
manyTill notEOL (try $ string " HTTP/1." <* oneOf "01")
<* crlf
以上snippet用于解析http请求..
变量ctor
位于左侧和右侧,
q name ctor body = liftM4 HttpRequest req url p_headers body --- ctor assigned a value
where req = ctor <$ string name <* char ' ' --- ctor used as a function
变量name
也可以在LHS和RHS上看到。
并且<$>
将所有列表元素映射到常量值。在这种情况下,
ctor <$ string name <* char ' '
它返回什么?
答案 0 :(得分:2)
表达式ctor <$ string name <* char ' '
的具体示例是:
Get <$ string "GET" <* char ' '
和
Post <$ string "POST" <* char ' '
Get
和Post
是GET和POST HTTP谓词的构造函数。它们可能来自如下的数据定义:
data HttpVerb = Get | Post | Head | ...
<$
运算符定义为fmap . const
(请参阅here)并且类型为:
<$ :: a -> f b -> f a
换句话说,它只是在函数中包装了a
,但在评估了它的第二个参数f b
之后。请注意,您通常会在此处看到<$>
,并忽略值b
。运算符中缺少>
用于指示忽略右侧的值。同样适用于<*
运营商。
因此,解析器计算Get <$ string "GET" <* char ' '
返回f Get
(其中f
是解析器函数),但前提是string "GET"
和char ' '
成功。
等效的monadic表达式是:
do string "GET"; char ' '; return Get