4

SICP の講義とテキストを使用して、Scheme について独学しています。「式 E の適用は (E E1,...En という形式の式です。これには、式 (E) に対応する n=0 の場合が含まれます。カリー化されたアプリケーション」という演習を見ています。 E のアプリケーションは、E のアプリケーションまたは E の Curried アプリケーションのアプリケーションです。」

(編集:上記の引用を修正しました...もともと定義を誤って引用していました。)

タスクは、3 に評価される手続きの Curried アプリケーションを定義することです。

(define foo1
    (lambda (x)
        (* x x)))

私はここでのアイデアを本当に理解していません. Curriying に関するウィキペディアのエントリを読んでも、あまり役に立ちませんでした.

ここで求められていることについて、より明確な説明を手伝ってくれる人はいますか?

この問題の後にさらに 5 つの解決すべき問題があるため、実際にこの問題の答えを教えていただけると助かります。... 基本的な考え方がわかりません。

追加: ブライアン・キャンベルの長い説明の後でさえ、私はまだ少し迷っています.

(foo1 (sqrt 3)))foo のアプリケーションと見なされるため、foo のカリー化されたアプリケーションと見なされますか?

単純すぎるようですが、多分...

(((foo1 2 )) 2)DrScheme に入力すると、次のエラーが表示されます (これは私が期待していたものです)。

procedure application: expected procedure, given: 4 (no arguments)

再読後カレーとは?foo1 を次のように再定義することもできることを理解しています。

(define (foo1 a)
    (lambda (b)
        (* a b)))

それで、私はタイプすることができます

((foo1 3 ) 4)

12

しかし、これは出力として 3 を生成することに実際には近づきません。これは、元の foo1 を実際にカリー化しているのではなく、再定義しているだけのようです。

くそー、C プログラミングの 20 年間は、これに対する準備ができていませんでした。:-) :-)

4

6 に答える 6

7

うーん、この問題は、通常はるかに明確なスタイルの本と比較して、かなり紛らわしい言い回しです。実際、ここから問題セットを取得している場合は、問題セットを誤って引用している可能性があります。それはあなたの混乱の一因となる可能性があります。

何が起こっているのかを理解するのに役立つかもしれないいくつかの例を使って、定義を分解します。

式Eの適用は、形式(E E1 ... En)の式です。

アプリケーションの例を次に示します。

(foo 1 2)      ; This is an application of foo
(bar 1)        ; This is an application of bar

これには、式(E)に対応するn=0の場合が含まれます。

(baz)          ; This is an application of baz

Eのカレードアプリケーションは、EのアプリケーションまたはEのカレードアプリケーションのアプリケーションのいずれかです。

これはあなたが誤って引用したものです。上記は私がオンラインで見つけた問題セットからの定義です。

この定義には2つの半分があります。最初から始めて:

Eのカレーアプリケーションは、Eのアプリケーションのいずれかです。

(foo 1 2)       ; (1) A Curried application of foo, since it is an application of foo
(bar 1)         ; (2) A Curried application of bar, since it is an application of bar
(baz)           ; (3) A Curried application of baz, since it is an application of baz

またはEのカレーアプリケーションのアプリケーション

((foo 1 2) 3)   ; (4) A Curried application of foo, since it is an application of (1)
((bar 1))       ; (5) A Curried application of bar, since it is an application of (2)
((baz) 1 2)     ; (6) A Curried application of baz, since it is an application of (3)
(((foo 1 2) 3)) ; A Curried application of foo, since it is an application of (4)
(((bar 1)) 2)   ; A Curried application of bar, since it is an application of (5)
                ; etc...

それはあなたが始めるのに必要な助けをあなたに与えますか?

編集:はい、(foo1 (sqrt 3))のカレードアプリケーションですfoo1; とても簡単です。多くの実装では、実際には2.9999999999999996などが得られるため、これはあまり良い質問ではありません。スキームに正確な代数的数の何らかの表現がない限り、正確に3を返す値を持つことはできません。

2番目の例は確かにエラーです。foo1適用するのに無効な整数を返します。関数のアプリケーションのアプリケーションの再帰的なケースが有効であるのは、後の例のほんの一部です。foo3たとえば、を見てください。

編集2:SICPをチェックインしたところ、ここでの概念はセクション1.3まで説明されていないようですが、この割り当てではセクション1.1についてのみ言及しています。まだ読んでいない場合は、セクション1.3を読んでみることをお勧めします。

于 2009-03-29T06:35:47.237 に答える
4

「カリー化」とは?を参照してください。

カリー化は、関数を取り、単一の引数を受け入れる新しい関数を提供し、指定された関数の最初の引数をその引数に設定して返します。

于 2009-03-29T07:06:11.893 に答える
3

James のカリー関数は正しくないと思います。私のスキーム インタープリターで試してみると、構文エラーが発生します。

これは、私がいつも使用している「カレー」の実装です。

> (define curry (lambda (f . c) (lambda x (apply f (append c x)))))
> ((curry list 5 4) 3 2)
(5 4 3 2)

関数への複数の引数のカリー化にも機能することに注意してください。

不十分な引数で呼び出したときに暗黙的にカリー化する関数を作成できるようにする、誰かが作成したマクロもあります: http://www.engr.uconn.edu/~jeffm/Papers/curry.html

于 2009-06-26T11:20:48.807 に答える
2

あなたは自分自身を混乱させすぎていると思います。関数をカリー化すると、型 F(a1,a2,...aN) の関数が取られ、それが a2 を取る関数を返す F(a1) に変換されます (これは a3 を取る関数を返します ... など)。

あなたが持っている場合:

(define F (lambda (a b) (+ a b)))
(F 1 2) ;; ==> 3

それをカリー化して、次のように動作するものを作成できます。

(define F (lambda (a) (lambda (b) (+ a b))))
((F 1) 2) ;; ==> 3

あなたの特定の質問の場合、それは非常に混乱しているようです。

(foo1 (sqrt 3))

適しているようです。今のところは置いておいて、本をもっと読むことをお勧めします。


簡単なカレーを実行する関数を実際に作成できます。

(define (curry f x) (lambda (y) (apply f (cons x y))))
(curry = 0) ;; a function that returns true if input is zero
于 2009-06-25T15:32:31.147 に答える
0

スキームの実装によっては、エラー/例外から回復できるユーティリティがいくつかある場合があります。たとえば、チキン スキームにはcondition-case.

(condition-case (func)
    ((exn) (print "error")))

任意の数の要素の関数を取り、カリー化された形式を返す関数を定義できます。

(define curry
    (lambda (func . args)
        (condition-case (apply func args)
           ((exn)
               (lambda plus
                   (apply curry func (append args plus)))))]))))

一度にあまりにも多くの引数を使用すると、最終的な結果が得られないため、これは少し醜いですが、これにより関数はカリー化された形式になります。

于 2013-03-04T17:51:22.983 に答える