首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell Parsec困境

Haskell Parsec困境
EN

Stack Overflow用户
提问于 2013-08-18 08:45:00
回答 1查看 445关注 0票数 5

我正在努力学习Parsec,并试图解析一个简单的电子邮件地址。我尝试了下面的代码。我的预期输出是作为字符串的整个电子邮件地址。但是当我运行代码时,我只能得到".com“,请告诉我发生了什么事?

代码语言:javascript
复制
{-# LANGUAGE NoMonomorphismRestriction #-}

import Text.Parsec
import Control.Applicative hiding ((<|>))

email = many1 alphaNum
     *> char '@'
     *> many1 alphaNum
     *> string ".com"

emailstr = parse email "" "xxxx@yyy.com"
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-18 09:01:02

*>的类型签名表示它从第二个解析器返回结果,并从第一个解析器丢弃结果。因此,email只返回序列中最终解析器的结果。

你可能想要的更像是

代码语言:javascript
复制
email =
  stitch
    <$> many1 alphaNum
    <*> char '@'
    <*> many1 alphaNum
    <*> string ".com"

这将运行四个解析器,并将每个解析器的结果作为参数传递给stitch。如果您为stitch编写了一个合适的实现

代码语言:javascript
复制
stitch a b c d = a ++ [b] ++ c ++ d

那你应该拿回你的绳子。

请注意,此时,您还可以将用户名和域放在数据结构或其他东西的单独字段中:

代码语言:javascript
复制
data Email = Email {username, domain :: String}

email =
  Email
    <$> many1 alphaNum
    <*  char '@'
    <*> ((++) <$> many1 alphaNum <*> string ".com")

现在,解析器返回一个Email结构,而不仅仅是一个普通字符串。这可能不是您想要的,但它演示了如何编写更复杂的解析器。

所有这些都是使用Parsec的Applicative接口,这通常被认为是很好的风格。使用Parsec的另一种方法是Monad接口:

代码语言:javascript
复制
email = do
  a <- many1 alphaNum
  b <- char '@'
  c <- many1 alphaNum
  d <- string ".com"
  return (a ++ [b] ++ c ++ d)
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18297333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档