原始递归 如果 那么 否则 实际执行 如果 否则 那么



我对If Then Else的定义中的投影有问题。它实际上是作为If-Else-then执行的。

import Prelude hiding (pred,and,or,not)
data PR = Z
| S
| P Int
| C PR [PR]
| PR PR PR
deriving Show
eval :: PR -> [Integer] - Integer
eval Z _ = 0
eval S [x] = x+1
eval (P n) xs = nth n xs
eval (C f gs) xs = eval f (map (g -> eval g xs) gs)
eval (PR g h) (0:xs) = eval g xs
eval (PR g h) (x:xs) = eval h ((x-1) : eval (PR g h) ((x-1):xs) : xs)
nth _ [] = error "nth nil"
nth 0 _ = error "nth index"
nth 1 (x:_) = x
nth (n) (_:xs) = nth (n-1) xs
one = C S [Z]
plus = PR (P 1) (C S [P 2])
ife = PR (P 1) (C (P 2) [P 3, P 4])

如果我尝试交换P 3P 4它就会完全中断(每次都返回"then"值)。ite[0,2,3]应该返回3ite[1,2,3]应该返回2。相反,情况正好相反。我该如何纠正此问题?

你觉得这个类怎么样?我注意到你和我的家庭作业非常相似,非常相似。

首先,你要做一个模拟IF-Then-Else模型的基元递归函数。 因此,

eval ite [0,1,2] => 1

eval ite [1,2,3] => 3

通过您提供的内容,您似乎在相反的实例中获得了一个具有相同质量的函数,具体取决于第一个输入。

ife = PR (P 1) (C (P 2) [P 3, P 4])

现在你的函数在说什么? 您的 ITE 实现使用原始递归构造,这是一个开始,因为在此中,您可以根据条件将执行拆分为两个不同的表达式。与布尔代数中使用的条件相同。如果 0 我们有 false,否则如果一个数字的计算结果为 (0<),我们有 true。PR 构造通过计算其第一个参数来实现这一点,如果"堆栈"的头部为 0,否则它会评估其第二个参数,希望它会在沿线的某个地方终止(通常时间递减头部作为计数器并最终执行第一个参数)。但出于所有意图和目的,我们可以说第二个表达式将在 (0<) 上执行。

唷!那么,我们如何修复您的实施!?容易:

ife = PR (P 2) (C (P 1) [P 3, P 4])

我们切换您的两个投影,因为您只是将它们倒过来。如果堆栈的头部是 Z,我们要投影第二个表达式,否则我们投影第一个表达式。 或者更好的是:

ite = PR (P 2) (P 1)

我想,我也没有完成家庭作业,如果我错了,我将非常感谢任何额外的见解。

由于我不够好,无法发表评论,因此我将将其留在这里。

我认为应该是

ife = PR (P 1) (C (P 2) [P 3, P 3])
^

而不是原始版本

ife = PR (P 1) (C (P 2) [P 3, P 4])
^

这样,如果第一个值不是 0 ELSE Y,则将选择 X。这样就不会返回随机值。此外,它使写作和/或/...更轻松。