Function 为什么haskell使用一种读取类型来表示函数?
我正在阅读Function 为什么haskell使用一种读取类型来表示函数?,function,haskell,Function,Haskell,我正在阅读reads的源代码读取定义为读取::读取a=>读取a 因此,它只返回读取a,而a必须是读取的实例 而ReadS a被定义为type ReadS a=String->[(a,String)],因此从ReadS返回的东西只不过是一个接受字符串并返回元组数组的函数 那么我想知道为什么只定义读取而不定义读取。就像 reads::reada=>(String->[(a,String)]) 事物的解析器 是字符串中的函数 到配对列表 所有的东西和绳子 -各种来源 它有助于对程序进行推理,从而根据抽
reads
的源代码<代码>读取定义为读取::读取a=>读取a
因此,它只返回读取a
,而a必须是读取
的实例
而ReadS a
被定义为type ReadS a=String->[(a,String)]
,因此从ReadS
返回的东西只不过是一个接受字符串并返回元组数组的函数
那么我想知道为什么只定义读取
而不定义读取。就像
reads::reada=>(String->[(a,String)])
事物的解析器是字符串中的函数
到配对列表
所有的东西和绳子 -各种来源 它有助于对程序进行推理,从而根据抽象的意图而不是实现来思考抽象。是的,虽然
类型读取a=String->[(a,String)]
,但这是解析事物和将读取的解析器链接在一起的实际目标的次要目标。正如所指出的那样:
composeReads :: ReadS a -> ReadS b -> ReadS (a,b)
传达了解析器组合的意图,并且作为一个愉快的副作用,它比内联的等价物更加简洁:
composeReads
:: (String -> [(a, String)])
-> (String -> [(b, String)])
-> (String -> [((a, b), String)])
排除这种重复是一件很好也很明显的事情,不仅因为这有利于避免重复,而且还可以尽可能增加每行有用的语义内容的数量。如果我们想改变这些解析器的实现方式,那么将它们封装在这个别名后面是一小步,这可以让我们避免对每个使用站点进行大规模更改
您可以在各种解析器组合器库中看到这一点,如Parsec、attopassec和uu parsinglib。解析器
是一个解析器
是一个解析器
,这些东西越像一个黑匣子,它们的使用和实现就越容易分开进行。基本上是可读性。给一个概念起一个名字可以让你更容易思考和谈论。例如:composeAds::ReadS a->ReadS b->ReadS(a,b)
比composeAds::(String->[(a,String)])->(String->[(b,String)]->(String->[(a,b,String)])
可读性更强。谢谢你的详细解释。我会记得“解析器就是解析器就是解析器,这些东西越像一个黑匣子,”:)