我正在努力学习Parsec,并试图解析一个简单的电子邮件地址。我尝试了下面的代码。我的预期输出是作为字符串的整个电子邮件地址。但是当我运行代码时,我只能得到".com“,请告诉我发生了什么事?
{-# LANGUAGE NoMonomorphismRestriction #-}
import Text.Parsec
import Control.Applicative hiding ((<|>))
email = many1 alphaNum
*> char '@'
*> many1 alphaNum
*> string ".com"
emailstr = parse email "" "xxxx@yyy.com"发布于 2013-08-18 09:01:02
*>的类型签名表示它从第二个解析器返回结果,并从第一个解析器丢弃结果。因此,email只返回序列中最终解析器的结果。
你可能想要的更像是
email =
stitch
<$> many1 alphaNum
<*> char '@'
<*> many1 alphaNum
<*> string ".com"这将运行四个解析器,并将每个解析器的结果作为参数传递给stitch。如果您为stitch编写了一个合适的实现
stitch a b c d = a ++ [b] ++ c ++ d那你应该拿回你的绳子。
请注意,此时,您还可以将用户名和域放在数据结构或其他东西的单独字段中:
data Email = Email {username, domain :: String}
email =
Email
<$> many1 alphaNum
<* char '@'
<*> ((++) <$> many1 alphaNum <*> string ".com")现在,解析器返回一个Email结构,而不仅仅是一个普通字符串。这可能不是您想要的,但它演示了如何编写更复杂的解析器。
所有这些都是使用Parsec的Applicative接口,这通常被认为是很好的风格。使用Parsec的另一种方法是Monad接口:
email = do
a <- many1 alphaNum
b <- char '@'
c <- many1 alphaNum
d <- string ".com"
return (a ++ [b] ++ c ++ d)https://stackoverflow.com/questions/18297333
复制相似问题