web-dev-qa-db-ja.com

Schemeで不特定の数のパラメータを処理するにはどうすればよいですか?

例えば ​​((fn-stringappend string-append) "a" "b" "c")私はこれを処理する方法を知っています(f x y z)。しかし、パラメーターの数が不明な場合はどうなりますか?この種の問題を処理する方法はありますか?

23
John

Schemeでは、ドット表記を使用して、可変数の引数を受け取るプロシージャを宣言できます(varargsまたは 可変個引数関数 とも呼ばれます)。

(define (procedure . args)
  ...)

procedure内では、argsは0個以上の引数が渡されたリストになります。このように呼んでください:

(procedure "a" "b" "c")

@Arafinweが指摘しているように、匿名プロシージャの同等の表記法は次のとおりです。

(lambda args ...)

このように呼んでください:

((lambda args ...) "a" "b" "c")

サイズが不明なリストのパラメーターを可変個引数関数に渡す必要がある場合は、次のように記述できることに注意してください。

(apply procedure '("a" "b" "c"))
(apply (lambda args ...) '("a" "b" "c"))

更新:

コメントのコードに関しては、これは意図したとおりに機能しません。

(define (fp f)
  (lambda (.z)
    (f .z)))

私はあなたがこれを意味したと信じています:

(define (fp f)
  (lambda z
    (apply f z)))

少しの構文糖衣構文を使用すると、上記の手順をさらに簡略化して次のようにすることができます。

(define ((fp f) . z)
  (apply f z))

しかし、それは単に書くには長い道のりです。

(apply f z)

これはあなたが必要なものですか?

(apply string-append '("a" "b" "c"))

とにかくそれは次と同等だからです:

(string-append "a" "b" "c")

string-appendalreadyは0個以上の引数を受け取ります(少なくとも、Racketの場合はそうです)

28
Óscar López

ÓscarLópezの答えに加えて、次のように可変引数の無名関数を作成することもできます。

(lambda args ...)

ここでも、lambda内で、argsは渡された引数のリストです。

7
Lily Chung