我正在阅读的源代码reads.reads被定义为reads :: Read a => ReadS a
它只是返回ReadS a而a必须是一个实例Read.
并且ReadS a被定义为type ReadS a = String -> [(a, String)],所以返回的东西reads只是一个函数,它接受一个字符串并返回一个元组数组.
然后我想知道为什么reads没有ReadS 定义a.就像
reads :: Read a => (String -> [(a, String)])
Jon*_*rdy 11
事物的解析器
是从字符串
到
事物和字符串列表的函数!- 各种来源
它有助于推理程序在其意图方面考虑抽象,而不是实现.所以是的,然而type ReadS a = String -> [(a, String)],这是解决事物的实际目标和将ReadS解析器链接在一起的次要因素.正如Rhymoid指出:
composeReads :: ReadS a -> ReadS b -> ReadS (a,b)
Run Code Online (Sandbox Code Playgroud)
传达解析器组合的意图,并且作为一个快乐的副作用比内联等效更简洁:
composeReads
:: (String -> [(a, String)])
-> (String -> [(b, String)])
-> (String -> [((a, b), String)])
Run Code Online (Sandbox Code Playgroud)
分解这种重复是一件好事而且显而易见的事情,不仅仅是因为避免重复是有益的,而且还要尽可能多地增加每行有用语义内容的数量.如果我们想要改变这些解析器的实现方式,那么将它们封装在这个别名后面是一小步,可以让我们避免对每个使用站点进行大量更改.
您可以在各种解析器组合库中重复这一点,例如Parsec,Attoparsec和uu-parsinglib.一个Parser是一个Parser是一个Parser,而更像是一个黑盒子这些东西,越容易与它们的使用发挥和implementation- 分开.
| 归档时间: |
|
| 查看次数: |
185 次 |
| 最近记录: |