parsing - 是否可以使用applicative来表达chainl1?

标签 parsing haskell parsec

是否可以不使用 Parsec 定义的 Monad 实例来表达 Parsec 的 chainl1 组合器?

chainl1 p op =
  do x <- p
     rest x
  where
    rest x = do f <- op
                y <- p
                rest (f x y)
          <|> return x

最佳答案

是的,是:

chainl1 p op = foldl (flip ($)) <$> p <*> many (flip <$> op <*> p)

这个想法是你必须解析 p (op p)*并将其评估为(...(((p) op p) op p)...)

稍微扩展一下定义可能会有所帮助:

chainl1 p op = foldl (\x f -> f x) <$> p <*> many ((\f y -> flip f y) <$> op <*> p)

作为 op 的对和p被解析,结果立即应用,但因为 pop 的右操作数,它需要 flip .

因此,结果类型为 many (flip <$> op <*> p)f [a -> a] 。然后,该函数列表从左到右应用于初始值p。通过foldl .

关于parsing - 是否可以使用applicative来表达chainl1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7719630/

相关文章:

haskell - 高阶可遍历仿函数是否有相应的光学器件?

java - 从抽象语法树中获取控制流图

ios - 我怎样才能确保 json 元素不为零?

java字符串解析

java - 如何将Iterator[String]转换为Reader实例进行解析?

python - 使用 pyparsing 累积

rest - Haskell Yesod - 执行 POST 请求时浏览器 OPTIONS 请求的 CORS 问题

多线程和 gtk2hs

使用 parsec 解析 sum 数据类型

parsing - 如何在 Haskell 中解析 float (Parsec.Combinator)