【发布时间】:2014-06-27 11:18:59
【问题描述】:
我是 Haskell 新手,我正在尝试编写一个解析器来评估一组特定的简单 Haskell 表达式。但是,当我事先不知道它们是什么类型时,我在使用函数时遇到了困难。
例如,假设我知道我要解析的字符串的计算结果是一个整数。以下是字符串可能是什么的几种可能性。
"succ 4"
"head [5,6,7]"
"sum [1,3,1]"
"length [a,b,c,d,e]"
"pred $ sum $ take 3 $ iterate succ 1"
天真地,我想为最后一个示例做的事情就是这样的过程。
解析出函数
pred,推断它的类型为(Enum a) => a -> a,并且我的字符串表示一个整数,而字符串的其余部分(在美元之后)仍然表示一个整数。解析出函数
sum并推断出我现在正在尝试评估整数列表。解析出函数
take并推断出我正在寻找一个整数和一个整数列表。解析出 3 并推断字符串的其余部分应该是整数列表。
解析出
iterate并推断我正在寻找Int -> Int类型的函数和一个整数。解析出
succ和1。执行评估。
问题在于,在流程的每个阶段,我遇到的下一个对象有许多可能的类型,如示例所示。所以我不能编写一些通用解析器来提取一个函数并留下一个表示其参数(或参数)的字符串。但是,如果我必须为每一种可能的函数编写单独的解析器,那么它很快就会变成一场噩梦,尤其是当我必须查看多个变量的函数时。
我意识到它并没有那么糟糕,因为许多函数是为几种不同的类型定义的。但是,例如,如果我说“如果字符串以“succ”开头,然后将其拉出并将 succ 应用于字符串其余部分的评估”,那么它会抱怨我应该指定我正在处理Enum 类中的一个类型。但是当我处理不在该类中的类型时,我遇到了麻烦。
完全披露:我正在使用 Graham Hutton 书中的简单解析器来构建我想要构建的东西。所以也许答案是有更高级的解析器来处理这类问题,我应该改用它。
【问题讨论】:
-
解析 Haskell 表达式不应该与类型有任何关系(除了像
[1, 3 .. 9 :: Int]中的实际显式注释)。只需将所有内容解析为无类型,然后您可以考虑在生成的 AST 上实现类型统一器。 — 显然,您不仅要解析代码,还要解释代码,但这是另一个问题,而且确实不像在动态语言中那样工作。像 Hugs 这样的 Haskell 解释器仍然通过“编译”经过类型检查的 AST 来工作。
标签: haskell interpreter