haskell - 身份解析器
问题描述
作为练习¹,我编写了一个仅使用char
解析器和Trifecta的字符串解析器:
import Text.Trifecta
import Control.Applicative ( pure )
stringParserWithChar :: String -> Parser Char
stringParserWithChar stringToParse =
foldr (\c otherParser -> otherParser >> char c) identityParser
$ reverse stringToParse
where identityParser = pure '?' -- ← This works but I think I can do better
解析器可以很好地完成它的工作:
parseString (stringParserWithChar "123") mempty "1234"
-- Yields: Success '3'
identityParser
然而,我对我申请的具体内容并不满意foldr
。必须为pure
.
我的第一个直觉是使用mempty
但Parser
不是幺半群。它是一个应用程序,但empty
构成一个不成功的解析器²。
相反,我正在寻找的是一个解析器,它在与其他解析器结合时作为中性元素工作。它应该什么都不做,即不推进光标并让下一个解析器使用该字符。
Trifecta 或其他库中是否有上述身份解析器?还是解析器不打算在 a 中使用fold
?
¹ 该练习来自Haskell Programming from first principle一书的解析器组合器章节。
² 正如cole 所指出的,Parser
是一个Alternative
,因此是一个幺半群。该empty
函数源于Alternative
, 而不是Parser
的应用实例。
解决方案
您不希望它解析 aString
吗?现在,从函数签名中可以看出,它解析 a Char
,返回最后一个字符。仅仅因为你只有一个Char
解析器并不意味着你不能制作一个String
解析器。
我将假设您要解析一个字符串,在这种情况下,您的基本情况很简单:您identityParser
的只是pure ""
.
我认为这样的事情应该有效(并且应该按照正确的顺序,但可能会颠倒过来)。
stringParserWithChar :: String -> Parser String
stringParserWithChar = traverse char
展开,你会得到类似的东西
stringParserWithChar' :: String -> Parser String
stringParserWithChar' "" = pure ""
stringParserWithChar' (c:cs) = liftA2 (:) (char c) (stringParserWithChar' cs)
-- the above with do notation, note that you can also just sequence the results of
-- 'char c' and 'stringParserWithChar' cs' and instead just return 'pure (c:cs)'
-- stringParserWithChar' (c:cs) = do
-- c' <- char c
-- cs' <- stringParserWithChar' cs
-- pure (c':cs')
如果它们不起作用,请告诉我,因为我现在无法测试它们……</p>
关于幺半群的题外话
我的第一个直觉是使用 mempty 但 Parser 不是幺半群。
啊,但事实并非如此。Parser是Alternative,它是Monoid。但是您实际上并不需要查看Alt
typeclassData.Monoid
来理解这一点;Alternative
的类型类定义看起来就像 aMonoid
的:
class Applicative f => Alternative f where
empty :: f a
(<|>) :: f a -> f a -> f a
-- more definitions...
class Semigroup a => Monoid a where
mempty :: a
mappend :: a -> a -> a
-- more definitions...
不幸的是,你想要的东西更像是一个产品而不是一个Alt
,但这就是默认行为的Parser
作用。
推荐阅读
- javascript - 打字稿无法导入 lodash
- antlr4 - 无法将 CPP14 加载为词法分析器或解析器
- angular - 除了 Angular 9 中的 LocalStorage 之外,在哪里存储当前用户?
- reactjs - 在 React 中加载更多按钮
- python - 连接列表 PYTHON
- node.js - Excel 中 CSV 文件的特殊字符问题,Sheetjs 为 utf8 CSV 文件添加 BOM
- javascript - Google Apps Script PropertiesService - 因不可靠的执行记录和编辑器调试而感到困惑
- azure-logic-apps - 逻辑应用部署 - 找不到集成帐户:工作流必须与集成帐户关联才能使用工作流运行操作
- wagtail - 如何在 Wagtail 中检索属于具有收藏权限的组的用户的图像?
- python - 使用 django 显示 404 错误处理页面