3

いくつかの作業の後で関数を理解することができましたが、次のコード(p。143)multirember&coからはあまり意味がありません。multiinsertLR&co

(define multiinsertLR&co
  (lambda (new oldL oldR lat col)
    (cond
     ((null? lat)
      (col '() 0 0))
     ((eq? (car lat) oldL)
      (multiinsertLR&co
       new
       oldL
       oldR
       (cdr lat)
       (lambda (newlat L R) 
         (col (cons new
                    (cons oldL newlat))
              (add1 L) R))))
     ((eq? (car lat) oldR)
      (multiinsertLR&co
       new
       oldL
       oldR
       (cdr lat)
       (lambda (newlat L R)
         (col (cons oldR
                    (cons new newlat))
              L (add1 R)))))
     (else
      (multiinsertLR&co
       new
       oldL
       oldR
       (cdr lat)
       (lambda (newlat L R)
         (col (cons (car lat)
                    newlat) L R)))))))

collectorこの本は、関数を評価するときに最初にどちらを渡す必要があるかを説明していないようです。そこで、それぞれ138ページと140ページで説明されているa-friendコレクターとコレクターを使用しました。last-friendいずれかのコレクターで関数を評価すると、次のエラーが発生します(petit chezスキームでトレース関数を使用)。

>> (multiinsertLR&co 'salty 'fish 'chips '(chips and fish or fish and chips) last-friend)

|(multiinsertLR&co salty fish chips (chips and fish or fish and chips)
   #<procedure>)
|(multiinsertLR&co salty fish chips (and fish or fish and chips)
   #<procedure>)
|(multiinsertLR&co salty fish chips (fish or fish and chips) #<procedure>)
|(multiinsertLR&co salty fish chips (or fish and chips) #<procedure>)
|(multiinsertLR&co salty fish chips (fish and chips) #<procedure>)
|(multiinsertLR&co salty fish chips (and chips) #<procedure>)
|(multiinsertLR&co salty fish chips (chips) #<procedure>)
|(multiinsertLR&co salty fish chips () #<procedure>)
Exception: incorrect number of arguments to #<procedure>
Type (debug) to enter the debugger.

コードを数回調べましたが、エラーが見つかりませんでした。誰かが何か洞察を持っているなら、それを共有してください。誰かが私に(比較的言えば)継続の穏やかな説明をいくつかの良い例とともに指摘することができれば、それも大いにありがたいです。

4

3 に答える 3

3

これが、クリスの2番目の例を解決するために行ったプロセスです。これは、行き詰まっている可能性のある他の人に役立つかもしれないと思ったからです。(エラーがある場合は修正してください!)

;; Anonymous functions (collectors) in mutliinsertLR&co here defined as named  
;; functions for reference purposes
(define left-col
  (lambda (newlat L R)
    (col (cons new
               (cons oldL newlat))
         (add1 L) R)))              ; L counter gets incremented

(define right-col
  (lambda (new lat L R)
    (col (cons oldR
               (cons new newlat))
         L (add1 R))))              ; R counter gets incremented

(define else-col
  (lambda (newlat L R)
    (col (cons (car lat)
               (newlat) L R))))     ; neither counter gets incremented

;; Let's step through an example to see how this works:
;;
;; 1. ENTRY TO FUNCTION
;; new  = foo
;; oldL = bar
;; oldR = baz
;; lat  = (goo bar baz qux quux)
;; col  = list
;;
;; 1. Is lat null? No.
;; 2. Is car of lat equal to oldL? No.
;; 3. Is car of lat equal to oldR? No.
;; 4. Else? Yes. Recur on the function passing the new, oldL
;;    oldR, (cdr lat) and the new collector.
;;
;; 2. FIRST RECURSIVE STEP
;; new  = foo
;; oldL = bar
;; oldR = baz
;; lat  = (bar baz qux quux)
;; col  = else-col
;;
;; - Is lat null? No.
;; - Is car of lat equal to oldL? Yes. Recur on the function
;;   passing new, oldL, oldR, (cdr lat), and the new col.
;;
;; 3. SECOND RECURSIVE STEP
;; new  = foo
;; oldL = bar
;; oldR = baz
;; lat  = (baz qux quux)
;; col  = left-col
;;
;; - Is lat null? No.
;; - Is car of lat equal to oldL? No.
;; - Is car of lat equal to oldR? Yes. Recur on the function
;;   passing new, oldL, oldR, (cdr lat), and the new col.
;;
;; 4. THIRD RECURSIVE STEP
;; new  = foo
;; oldL = bar
;; oldR = baz
;; lat  = (qux quux)
;; col  = right-col
;;
;; - Is lat null? No.
;; - Is car of lat equal to oldL? No.
;; - Is car of lat equal to oldR? No.
;; - Else? Yes. Recur on the function passing new, oldL, oldR,
;;   (cdr lat) and the new collector.
;;
;; 5. FOURTH RECURSIVE STEP
;; new  = foo
;; oldL = bar
;; oldR = baz
;; lat  = (quux)
;; col  = else-col
;;
;; - Is the lat null? No.
;; - Is the car of lat equal to oldL? No.
;; - Is the car of lat equal to oldR? No.
;; - Else? Yes. Recur on the function passing new, oldL, oldR,
;;   (cdr lat) and the new collector.
;;
;; 6. FIFTH RECURSIVE STEP
;; new  = foo
;; oldL = bar
;; oldR = baz
;; lat  = ()
;; col  = else-col
;;
;; - Is the lat null? Yes. Call else-col, where newlat is (),
;;   L is 0 and R is 0.
;;
;; 7. ELSE-COL
;; newlat = ()
;; L      = 0
;; R      = 0
;; col    = else-col
;;
;; - Now call else-col on the (cons (car lat)), which is currently
;;   stored in memory as the atom "quux", onto newlat, as well as
;;   L and R.
;;
;; 8. ELSE-COL (again)
;; newlat = (quux)
;; L      = 0
;; R      = 0
;; col    = right-col
;;
;; - Now call right-col on the (cons (car lat)), which is currently
;;   stored in memory as the atom "qux", onto newlat, as well as L
;;   and R.
;;
;; 9. RIGHT-COL
;; newlat = (qux quux)
;; L      = 0
;; R      = 0
;; col    = left-col
;;
;; - Now call left-col on the cons of oldR and (cons new newlat),
;;   as well as L and the increment of R.
;;
;; 10. LEFT-COL
;; newlat = (baz foo qux quux)
;; L      = 0
;; R      = 1
;; col    = else-col
;;
;; - Now call else-col on the cons of new and (cons oldL newlat),
;;   as well as the increment of L and R.
;;
;; 11. ElSE-COL (last time)
;; newlat = (foo bar baz foo qux quux)
;; L      = 1
;; R      = 1
;; col    = list
;;
;; - Now we call list on the (cons (car lat)), which is currently
;;   stored in memory as the atom "goo", onto newlat, as well as L
;;   and R.
;; - This gives us the final, magical list:
;;   ((goo foo bar baz foo qux quux) 1 1)
;;
;; 12. FIFTH RECURSIVE STEP (redux)
;; new  = foo
;; oldL = bar
;; oldR = baz
;; lat  = (quux)
;; col  = else-col
;;
;; - Base case evaluated, with the result being
;;   ((goo foo bar baz foo qux quux) 1 1).
;; - Function ends.
;;
;; THE END
于 2012-09-01T04:52:51.107 に答える
2

コードの基本ケースに見られるように、コレクター/継続は3つの引数を取る必要があります。渡さない関数を渡したようです。


あなたが取り組んだのは良いことですmultirember&co:私はそれについての答えを書きました、あなたがレビューしたいかもしれません

とにかく、これらのコレクター/継続をテストする際の一般的なアプローチは、list継続として使用することから始めることです。これlistは、可変個引数であり、リストとして指定されたアイテムを返すだけだからです。次に例を示します。

> (multiinsertLR&co 'foo 'bar 'baz '(foo bar baz qux quux) list)
'((foo foo bar baz foo qux quux) 1 1)

ああ、2つ見えますfoo!どちらが挿入され、どれが元のリストに含まれていましたか?

> (multiinsertLR&co 'foo 'bar 'baz '(goo bar baz qux quux) list)
'((goo foo bar baz foo qux quux) 1 1)

ああ、それで私たちは何かに取り組んでいます!リストにが含まれているbar場合は常に、fooその前にが挿入されます。リストにが含まれている場合は常に、リストのbazfooにが挿入されます。しかし、数字は?

> (multiinsertLR&co 'foo 'bar 'baz '(baz goo bar baz qux bar quux baz) list)
'((baz foo goo foo bar baz foo qux foo bar quux baz foo) 2 3)

それらの数字はカウンターのように見えます!「左」に挿入するたびに最初のカウンターがインクリメントされ、「右」に挿入するたびに2番目のカウンターがインクリメントされます。


コードを見ると、の各ブランチをcond見ると、左一致の場合、右一致の場合、および不一致の場合(そしてもちろん、の終わり)で何が起こるかがわかります。 -ベース/初期値を設定するリストケース)。いずれの場合も、挿入(およびカウンターインクリメント)がどのように行われるかに注意してください。すでに取得しているのでmultirember&co、これからはかなり簡単になります。ではごきげんよう!

于 2012-08-31T14:42:03.717 に答える
0

最近、これを私のお気に入りのパターンマッチング擬似コードで書き直します。1これにより、はるかにコンパクトで視覚的にわかりやすくなります。

multiinsertLR&co new oldL oldR lat col  =  g lat col 
  where
  g [a, ...t] col 
    | a == oldL  =  g t  ( newlat L R =>  col [new, oldL, ...newlat] (add1 L)  R  )
    | a == oldR  =  g t  ( newlat L R =>  col [oldR, new, ...newlat]  L  (add1 R) )
    | else       =  g t  ( newlat L R =>  col [a,         ...newlat]  L        R  )
  g [] col       =                        col []                      0        0

;のsLの数も同様です。のsの数です。とは、作成される結果のリストに挿入される特別な要素であり、入力されたアトムのリストの要素の右側と左側にあります。oldLlatRoldRlatnewoldRoldLlat

multii&co 0 1 2 [1,4,5,2,4,5,1,4,5,1] col 
=
col [0,1,4,5, 2,0,4,5, 0,1,4,5, 0,1 ] 3 1

そしてそれがすべてです。便利な表記法で、それは十分に簡単です。


1これこれを参照してください。

于 2018-01-24T19:45:18.733 に答える