Haskell Concat解析结果

Haskell Concat解析结果,haskell,parsec,Haskell,Parsec,我可以创建一个解析器,它可以处理两个或三个用逗号分隔的数字,如下所示: number :: Parser Int number = many1 digit >>= return . read <?> "number" numbers = do n1 <- number n2 <- char ':' >> number n3 <- optionMaybe $ char ':' >> number return ..

我可以创建一个解析器,它可以处理两个或三个用逗号分隔的数字,如下所示:

number :: Parser Int
number = many1 digit >>= return . read <?> "number"

numbers = do
  n1 <- number
  n2 <- char ':' >> number
  n3 <- optionMaybe $ char ':' >> number
  return ... -- return all of n1, n2, n3
val result = input.parseAs(numbers) {
  case n1 ~ n2 ~ None => // work with n1,n2
  case n1 ~ n2 ~ Some(n3) => // work with n1,n2,n3
}
我想这样做是为了在不同的地方对解析器进行模式匹配。例如,在Scala中,我可以执行以下操作:

number :: Parser Int
number = many1 digit >>= return . read <?> "number"

numbers = do
  n1 <- number
  n2 <- char ':' >> number
  n3 <- optionMaybe $ char ':' >> number
  return ... -- return all of n1, n2, n3
val result = input.parseAs(numbers) {
  case n1 ~ n2 ~ None => // work with n1,n2
  case n1 ~ n2 ~ Some(n3) => // work with n1,n2,n3
}

其中输入是要分析的字符串。parsec是否具有允许类似行为的内置函数?如果不是,我自己如何构建这样的行为?

您可以使用应用程序函子来实现。模式通常是:

import Control.Applicative

f <$> a1 <*> a2 <*> a3
(,)
是3元组的构造函数,因此它是一个接受3个参数并返回3元组的函数。通过
模式传递3个解析器,将3元组构造函数的应用程序提升到此处使用的函子中,在本例中为
Parser
,因此整个表达式返回函子中封装的映射函数的结果,即
解析器(Int,Int,可能Int)

您也可以使用
liftA3 f a1 a2 a3
代替
f a1 a2 a3
;这两个表达式是等价的

PS.您也可以使用应用程序函子定义
number
(monad接口更“重”,我个人尽量避免):

number::解析器Int
数字=读取多个1位数的“数字”
number :: Parser Int
number = read <$> many1 digit <?> "number"