原始递归函数

时间:2012-11-24 23:52:41

标签: haskell recursion

我正在尝试在Haskell中定义一些basic Primitive Recursive函数。为什么我的times函数递归次数太多次(即eval times[x,y]导致(x+1)*y)?我认为我的问题通常是由于对Composition函数的工作原理认识不足。请不要在没有解释的情况下给出答案以澄清我的理解。

 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])
 times = PR (P 1) (C plus [P 2, P 3])

我已经为times最近的times = PR (P 1) (C plus[P 2, P 2]尝试了一些其他的事情,但这是2x*y的问题。我想“好吧我只会替换其中一个P 2与} Z然后它将是x*y“这实际上使它成为y的身份函数,我不明白为什么。

2 个答案:

答案 0 :(得分:3)

这个时代的定义似乎有效:

times' = PR Z (C plus [P 2, P 3])

*Main> eval times' [6,7]
42

这是有道理的,因为0 * x = 0而不是1。

请注意,我必须更改eval (C ...)的定义才能进行编译:

eval (C f gs) cs = eval f (map (\g -> eval g cs) gs)

更详细的解释......

我们知道某些times PR Z h的格式为h

让我们展开eval (PR Z h) (x+1:y:ys) ...

eval (PR z h) (x+1:y:ys)
    = eval h ((x+1-1) : eval (PR g h) ((x+1-1):y:ys) : y : ys)
    = eval h (x : eval (PR Z h) (x:y:ys) : y : ys)
    = eval h (x : x*y : y : ys)

因为通过归纳我们知道eval (PR z h) (x:y:ys) = x*y

那么h必须是什么才能获得(x+1)*y = y+x*y?我们需要添加yP 3}和x*yP 2),因此我们应将h定义为:

h = C plus [P 2, P 3]

如果您使用P 1代替Z,那么您的基本案例为y而不是0

eval (PR (P 1) ...) (0:y) = eval (P 1) (y) = y

递归保持不变,因此您在答案中的距离为y

答案 1 :(得分:3)

假设op的格式为PR something (C otherThing projections)。然后,如果x > 0

eval op [x,y]

呼叫

eval (C otherThing projections) [x-1, (x-1) `op` y, y]

otherThing是由排名较高的op组成的操作。在更简单的情况下,您只想在递归调用的结果(x-1) `op` yy上调用它,因此投影应该选择参数列表的第二个和第三个元素。

因此我们有

times = PR something (C plus [P 2, P 3])

因为我们有递归方程

x*y = (x-1)*y + y

不涉及孤立的x-1

现在,当到达基本案例x == 0时,递归调用应该返回基本结果。对于乘法,当然是0,因此something应该Z,独立于y,而y不会P 1给你。{ / p>

因此,作为user5402 said,您应该

times = PR Z (C plus [P 2, P 3])