我正在尝试使用Guile Scheme在终端上打印Pascal的三角形 What is Pascal's Triangle?
这是脚本:
#!/usr/local/bin/guile \
-e main -s
!#
(define (fact-iter product counter max-count)
(if (> counter max-count)
product
(fact-iter (* counter product) (+ counter 1) max-count)))
(define (factorial n)
(fact-iter 1 1 n))
(define (n-C-r n r)
(/ (factorial n) (* (factorial (- n r)) (factorial r))
)
)
(define (row-iter r l n)
(cond ((= r 0) ((display 1) (row-iter (+ r 1) l n)))
((and (> r 0) (< r l)) ((display (n-C-r l r)) (display " ") (row-iter (+ r 1) l n)))
((= r l) (display 1))
)
)
(define (line-iter l n)
(cond ((<= l n) ( (row-iter 0 l n)
(line-iter (+ l 1) n) ) )
)
)
(define (pascal-triangle n)
(line-iter 0 n) )
(define (main args)
(pascal-triangle (string->number (car (cdr args)) 10))
)
文件名是pascalTriangle.scm
顶部的 Shebang符号具有正确的guile路径
我通过 chmod + x pascalTriangle.scm
给予了权限
使用 ./ pascalTriangle.scm 5
运行时,上面的脚本会出现以下输出/错误:
1Backtrace:在ice-9 / boot-9.scm中:
157:5 [catch #t#&lt; catch-closure ac8400&gt; ...]
在未知档案中:
?:4 [apply-smob / 1#&lt; catch-closure ac8400&gt;]
在ice-9 / boot-9.scm中:
63:3 [call-with-prompt prompt0 ...]
在ice-9 / eval.scm中:
432:2 [eval ##]
在/home/tarunmaganti/./pascalTriangle.scm中:
27:1 [line-iter 0 4]
在未知档案中:
?:0 [#&lt;未指定&gt; #&lt; unspecified&gt;]错误:在程序#&lt;未指定&gt;:
错误:要应用的类型错误:#&lt; unspecified&gt;
请注意,输出的第一个字符是1,这意味着代码执行到程序的第一部分 row-iter 即(显示1)并且之后可能会出现错误。
但输出显示错误在程序 line-iter 中。我不明白。
如果程序中的任何错误被指出并更正以使其打印Pascal的三角形,我将不胜感激。
Edit1:我编辑了错误/输出文本,我替换了'&lt;'和'&gt;'与HTML实体。角括号内的文字以前是不可见的。
答案 0 :(得分:1)
问题是你在cond
中的后果表达式周围添加了多余的括号。由于cond
明确begin
,因此您的代码今天看起来像这样:
(define (row-iter r l n)
(cond ((= r 0)
;; you see the double (( ?
((display 1)
(row-iter (+ r 1) l n)))
((and (> r 0) (< r l))
;; you see the double (( ?
((display (n-C-r l r))
(display " ")
(row-iter (+ r 1) l n)))
((= r l)
;; without double (( and thus ok
(display 1))))
需要删除多余的括号,如下所示:
(define (row-iter r l n)
(cond ((= r 0)
(display 1)
(row-iter (+ r 1) l n))
((and (> r 0) (< r l))
(display (n-C-r l r))
(display " ")
(row-iter (+ r 1) l n))
((= r l)
(display 1))))
如果您使用if
,则必须使用begin
:
(define (row-iter r l n)
(if (= r 0)
(begin
(display 1)
(row-iter (+ r 1) l n))
(if (and (> r 0) (< r l))
(begin
(display (n-C-r l r))
(display " ")
(row-iter (+ r 1) l n))
(display 1))))
修复此过程不会解决您的问题,因为您在line-iter
中也有相同的错误。您可能会在每个((
字词的开头看到双cond
,但除非您正在做一些奇特的事情,否则您不应该在其他任何地方期待它。
当添加多余的括号((display "something") #t)
时,它被解释为(display "something")
将返回一个过程,并且您想要检查具有参数#t
的该过程的结果将变为什么。当评估所有部件时,它失败,因为它发现未定义的值不是过程。有些情况下有效:
((if (< x 0) - +) x 1) ; absolute increment value without changing sign
在这里,当-
小于零时,您会看到第一部分被评估为评估x
的结果。如果它是-10
,则结果为-11
,如果是10
,则应用的过程将是对+
的评估,结果为11
稍后它会发现值3
不是一个程序,你就会发现错误。并得到结果Scheme应该做(应用3&#39;(#t))and it detects that 3 (in your case what
desiplay returns which is an unspecified value)
Scheme interprets this by evaluating
(显示(nCr lr)`打印一些东西和返回值,由规范由于括号过多,我未定义并因此自由选择实施者,然后作为程序应用。
在Guile中,规范中未定义的值的结果变为显示#<unspecified>
的单例,并且被REPL忽略。您可能会发现一个Scheme实现,其中未指定的值是一个不带参数的过程,其中您的实现将完美地工作但不可移植。
答案 1 :(得分:0)
Sylwester在答案中陈述的错误是((display (n-C-r l r)) (display " ") (row-iter (+ r 1) l n)))
表达式。该语句确实通过评估((display (n-C-r l r))
来解释这一点,((display (n-C-r l r))
打印一些东西并返回未定义的值,并作为一个程序应用,将(begin <e1> <e2> <e3>....<en>)
视为过分括号。
我使用Sequencing解决了这个问题。 开始特殊表单用于组合多个语句并返回最后一个语句的值。 Sequencing in MIT-Scheme。这也适用于guile计划。
开始特殊形式的语法:<en>
它返回(define (row-iter n r)
(cond ((= r 0) (begin (display 1) (display " ") (row-iter n (+ r 1))))
((and (> r 0) (< r n)) (begin (display (n-C-r n r)) (display " ") (row-iter n (+ r 1))))
((= r n) (display 1))
)
)
表达式的返回值。
以下是更改后的代码:
./pascalTriangle 5
虽然输出没有正确格式化为“三角形”,但我们可以在更改代码后得到左缩进的pascal三角形。
通过运行 1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
,我们将输出视为
break