4

リストを別の関数/手順に送信し、リストからアイテムを削除し、新しいリストを更新 (削除されたアイテム)、最初の関数/手順から表示するにはどうすればよいですか。

また、セットを使用できることも知っています。リストを更新しますが、 set! 「スキームの方法」ではありません。

しかし、この方法以外にこのプログラムを作成する方法がわかりません(これは機能しません):

#lang racket

(define list1 '("read" "id" "$$"))

(define (displayer list1)
  (remover list1)
  (newline)
  (display list1)) ;also doesn't display updated list here

(define (remover list1)
  (remove "$$" list1)
  (display list1))  ;doesn't display updated list here

ありがとう!

4

3 に答える 3

3

質問で述べたように、これは本当にSchemeで物事を行う方法ではありません。set!それにもかかわらず、グローバルな定義を行い、初期バインディングの再定義を可能にする言語を選択することで、Racket で求めていることを達成することができます。違う。

とにかく、ここに方法があります:

(define list1 '("read" "id" "$$"))

(define (displayer)
  (remover)
  (newline)
  (display list1))

(define (remover)
  (set! list1 (remove "$$" list1))
  (display list1))

(displayer)
> (read id)
> (read id)

より慣用的なアプローチは、グローバル変数を定義してプロシージャ内で変更することを避けることです。代わりに、リストを変更する必要があるたびに、新しいリストを作成し (新しいリストを作成removeします)、次のように渡します。

(define (displayer lst)
  (let ((removed (remover lst)))
    (newline)
    (display removed)))

(define (remover lst)
  (let ((removed (remove "$$" lst)))
    (display removed)
    removed))

(define list1 '("read" "id" "$$"))
(displayer list1)
> (read id)
> (read id)

2 番目の解決策は を変更しないことに注意してくださいlist1。これが問題を解決する機能的な方法です。

于 2012-04-28T04:37:19.570 に答える
3

私が書いた場合、あなたのコードで:

(displayer list1)

次のように表示されます。

(read id $$)

しかし、次のように変更すると:

#lang racket

(define list1 '("read" "id" "$$"))

(define (displayer list1)
   (display (remover list1))) 

(define (remover list1)
  (remove "$$" list1)) 

走るときはこのように

(displayer list1)

戻ってきます

(read id)

関数型言語では、すべてが式であり、可変ではない「変数」を扱うことが推奨される方法であることを思い出してください (状態なしで作業すると、プログラムの検証、最適化、および並列化が容易になり、それらのタスクを実行するための自動化ツールを簡単に作成できます。ここで詳細を読む: http://en.wikipedia.org/wiki/Functional_programming#Comparison_to_imperative_programming ) したがって、リストから要素を削除してから表示する場合は、要素の少ない新しいリストを返す関数を作成する必要があります。

一方、Racket は Haskell のような純粋な関数型言語ではないため、おっしゃったように、変数 "list1" によって参照される値を本当に再定義したい場合は、次のような命令型の方法で Racket を使用できます。

#lang racket
(define list1 '("read" "id" "$$"))

(define (displayer list1)
  (set! list1 (remover list1))
  (newline)
  (display list1)) 

(define (remover list1)
  (remove "$$" list1))  

セット!今後、新しい値を指すように list1 をリダイレクトします

詳細については、http: //htdp.org/2003-09-26/Book/curriculum-ZH-44.htmlを参照してください。

于 2012-04-28T03:56:32.343 に答える
1
(remove "$$" list1)

list1「$$」を削除して戻りますが、変更されません list1。したがって、解決策は、呼び出しでdisplayをremover呼び出すことです。

(display (remover list1))

「$$」を削除するために再実装removerしますが、他の副作用はありません(出力は副作用です)。

(define (remover list1) (remove "$$" list1))
于 2012-04-28T04:29:13.380 に答える