質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

LISP

LISPはプログラミング言語の一種であり、関数型言語に分類されています。 特徴として、括弧を多様する独特の構文を持ちます。

Q&A

1回答

254閲覧

Schemeのコードで、何故定義してある関数をlambdaで書かなければならないのか?

tochu_cha

総合スコア12

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

LISP

LISPはプログラミング言語の一種であり、関数型言語に分類されています。 特徴として、括弧を多様する独特の構文を持ちます。

0グッド

0クリップ

投稿2017/09/04 16:39

湯浅太一著「Scheme入門」を読んでおります。
その8章の例題問題、8.2.2の解答を見て、疑問があります。

lisp

1 2(define (diff-fmla fmla var) 3 (cond ((symbol? fmla) 4 (if (eq? fmla var) 1 0)) 5 ((number? fmla) 0) 6 (else 7 (case (car fmla) 8 ((+) (cons '+ 9 (map (lambda (f) (diff-fmla f var)) 10 (cdr fmla)))) 11 ((*) (cons '+ 12 (map (lambda (f) (cons '* f)) 13 (diff-*-args (cdr fmla) var)))) 14 ((^) (list '* 15 (caddr fmla) 16 (list '^ 17 (cadr fmla) 18 (- (caddr fmla) 1)) 19 (diff-fmla (cadr fmla) var))) 20 ((-) (list '- 21 (diff-fmla (cadr fmla) var))))))) 22 23 24(define (diff-*-args fmlas var) 25 (if (null? fmlas) 26 '() 27 (cons (cons (diff-fmla (car fmlas) var) 28 (cdr fmlas)) 29 (map (lambda (fs) (cons (car fmlas) fs)) 30 (diff-*-args (cdr fmlas) var))))) 31

これは例えば

lisp

1(diff-fmla '(+ (^ x 2) (* x 2) 'x)

を評価すると

lisp

1(+ (* 2 (^ x 1) 1) (+ (* 1 2) (* x 0)))

と導関数を返す関数です。


疑問なのはまず diff-fmla 関数の

lisp

1((+) (cons '+ 2 (map (lambda (f) (diff-fmla f var)) 3 (cdr fmla))))

です。この

lisp

1(map (lambda (f) (diff-fmla f var)) 2 (cdr fmla))

の部分は

lisp

1(map diff-fmla (cdr fmla) var)

と同じように思えるのですが、何故lambdaでdiff-fmlaを書かなければならないのでしょうか?
ちなみに私に思えたように書いてみると、Errorになりました。


. 次にdiff-*-args関数内の

lisp

1(map (lambda (fs) (cons (car fmlas) fs)) 2 (diff-*-args (cdr fmlas) var))

です。mapのあとにconsを書くならば、何となく

lisp

1(map cons 'a '((1) (2)))

とすれば

lisp

1((a 1) (a 2))

になるように思えるのですが、実際にはこれもエラーになります。mapの後に引数を2つ取る関数(例えばcons)を置くならば、lambdaで一つ一つ書かなければならないのでしょうか?

この2ヶ所がよく納得行きません。お分かりの方、どうかよろしくご教授のほどお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

mapの後に引数を2つ取る関数(例えばcons)を置くならば、lambdaで一つ一つ書かなければならないのでしょうか?

質問文中のコードの範囲でざっくりいうと「はい」です。

引数を2つ取る関数の場合、原則として同じ数だけ並べた2つのリストを指定します。

lisp

1(map cons '(a a a) '((1) (2) (3)))

同じ要素を繰り返す場合、circular-listで循環リストにするという手もありますが、lambdaを使ったほうが意図が明快なように思います(主観ですが)。

lisp

1(use srfi-1) 2(map cons (circular-list 'a) '((1) (2) (3)))

2引数の関数のうち1つの引数を固定して1引数の関数を作るには、部分適用という方法もあります。

lisp

1(map (cut cons 'a <>) '((1) (2) (3)))

投稿2017/09/04 18:22

emasaka

総合スコア524

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問