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"