0

Guile Scheme を使用して端末にパスカルの三角形を出力しようとしています。
パスカルの三角形とは?

スクリプトは次のとおりです。

 #!/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: in ice-9/boot-9.scm:
   157: 5 [catch #t #<catch-closure ac8400> ...]
In unknown file:
     ?: 4 [apply-smob/1 #<catch-closure ac8400 >]
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]
In unknown file:
     ?: 0 [#<unspecified> #<unspecified>]

エラー: プロシージャ内 #<unspecified>:
エラー: 適用する型が間違っています: #<unspecified>

出力の最初の文字が 1 であることに注意してください。これは、コードがプロシージャrow-iterの最初の部分(表示 1) まで実行され、その後にエラーが発生する可能性があることを意味します。

しかし、出力は、エラーがプロシージャline-iterにあることを示しています。理解できません。
プログラムの誤りを指摘し、パスカルの三角形を表示するように修正していただければ幸いです。

Edit1: エラー/出力テキストを編集し、'<' と '>' を HTML エンティティに置き換えました。角かっこ内のテキストは、以前は表示されませんでした。

4

2 に答える 2

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 は (apply 3 '(#t)) and it detects that 3 (in your case whatdesiplay returns which is an unspecified value) Scheme interprets this by evaluating(display (nCr lr)` を実行する必要があります) 何かを出力し、返された値を出力します。これは、仕様によって定義されていないため、実装者の自由な選択が適用されます。括弧が多すぎるため、プロシージャとして。

Guile では、仕様で定義されていない値の結果は表示されるシングルトンになり#<unspecified>、REPL によって無視されます。未指定の値が引数を取らない手続きである Scheme 実装を見つけるかもしれません。実装は問題なく動作しますが、移植性はありません。

于 2016-06-24T10:28:54.110 に答える