【发布时间】:2021-07-04 12:22:27
【问题描述】:
我正在研究 Haskell lambda 演算解释器。我有一种方法可以将表达式简化为正常形式。
type Var = String
data Term =
Variable Var
| Lambda Var Term
| Apply Term Term
deriving Show
normal :: Term -> Term
normal (Variable index) = Variable index
normal (Lambda var body) = Lambda var (normal body)
normal (Apply left right) = case normal left of
Lambda var body -> normal (substitute var (normal right) body)
otherwise -> Apply (normal left) (normal right)
如何将采取的步骤保存到集合中?
我的正常功能输出如下:
\a. \b. a (a (a (a b)))
我的目标是完成所有步骤:
(\f. \x. f (f x)) (\f. \x. f (f x)),
\a. (\f. \x. f (f x)) ((\f. \x. f (f x)) a),
\a. \b. (\f. \x. f (f x)) a ((\f. \x. f (f x)) a b),
\a. \b. (\b. a (a b)) ((\f. \x. f (f x)) a b),
\a. \b. a (a ((\f. \x. f (f x)) a b)),
\a. \b. a (a ((\b. a (a b)) b)),
\a. \b. a (a (a (a b)))]
我尝试将普通方法封装到列表中,如下所示:
normal :: Term -> [Term]
normal (Variable index) = Variable index
normal (Lambda var body) = term: [Lambda var (normal body)]
normal (Apply left right) = case normal left of
Lambda var body -> normal (substitute var (normal right) body)
otherwise -> Apply (normal left) (normal right)
但这似乎不是正确的方法。
【问题讨论】:
-
您能否在输入和预期输出中包含完整的
Terms? -
看起来最像 Haskell 的方式是为术语创建一些光学。每个标准化步骤都会得到一个完整的 Term 和一些镜头,并输出一个可选的新 Term 和要尝试的新镜头列表。如果你得到一个新的术语,这意味着一个标准化步骤已经完成,你需要将旧术语添加到日志中并继续使用新术语。如果您有一些镜头,请将它们添加到现有列表中。在每个步骤中,您从列表中取出第一个镜头并运行它。如果你有一个空的镜头列表,你就完成了。注意我不一定知道我在说什么,用盐调味。
-
@bwroga 不确定我是否理解您的意思。像一个术语的例子?
-
@n.1.8e9-where's-my-sharem。我可能误解了你的想法。但是,每次匹配最后一个模式时我都在规范化还不够,因此将列表保存步骤合并到代码中就足够了吗?正常功能似乎工作正常,因此我只需要在每次它计划递归时保存该步骤,这不是有效吗?
-
如果您包含
substitute的定义,那就太好了。我相信你它有效并且不是问题的重点,但是在解决问题时,很高兴能够测试它是否产生正确的结果。