汉诺塔,Python转Scheme,出现错误。我漏掉了什么?

4 投票
1 回答
1353 浏览
提问于 2025-04-15 19:51

这是一个关于Python实现的内容。

import sys

def move(src, dst, tmp, num):
    if num == 1: print 'Move from', src, 'to', dst
    else:
        move(src, tmp, dst, num-1)
        move(src, dst, tmp, 1)
        move(tmp, dst, src, num-1)

move('left', 'right', 'middle', int(sys.argv[1]))

这个代码能正确解决汉诺塔问题。但是我的方案移植,

(define move
    (lambda (src dst tmp num)
      (if (= num 1) (printf "Move from ~s to ~s \n" src dst)
          ((move src tmp dst (- num 1))
           (move src dst tmp 1)
           (move tmp dst src (- num 1))))))

也能给出正确的解决方案,但最后却出现了以下错误。

procedure application: expected procedure, given: #<void>; arguments were: #<void> #<void>

我知道是我的打印语句导致了这个错误,但我搞不清楚为什么会这样?

1 个回答

4
 ((move src tmp dst (- num 1))
  (move src dst tmp 1)
  (move tmp dst src (- num 1)))

上面的代码并不是你想的那样运行哦 :)

如果你想执行一系列的表达式或语句,你需要像这样做:

((λ ()
  (move src tmp dst (- num 1))
  (move src dst tmp 1)
  (move tmp dst src (- num 1))))

在Scheme中,语法糖是指

(begin
   (move ...)
   (move ...)
   (move ...)
   ...)

((move ...) (move ...) (move ...))

这些代码会被计算,看起来是正常工作的。但是一旦递归结束,
解释器会尝试把它当作 (op param1 param2) 来执行,这时候就会出现错误 #<void>; arguments were: #<void> #<void>

撰写回答