1

来週には中間試験があり、クラスで提供された sml ノートを調べていました。カリー化の例に出くわしましたが、それがどのように機能するか正確にはわかりませんでした。

数の累乗を計算する単純な関数です。関数定義は次のとおりです。

fun pow 0 n = 1 | pow k n = n*pow(k-1)n

次の引数を渡すと、この関数がどのように機能するかわかりません。

val x = pow 2 2

これは私がそれを見る方法です:

=2*pow(1)2
=2*(2*pow(0)2)2
=2*(2*(1)2)2) 

得られるはずの結果は 4 ですが、上記で実行した手順からこの結果が得られる方法がわかりません。

助けてください。ありがとうございました。

4

2 に答える 2

2

ああ、ニュージャージーの標準 ML さん、あなたがいなくて寂しいです...

とにかく、この手順を順を追って説明します。カリー化は、目の前の夕食 (ちなみにこれはカレー料理です) とは異なり、基本的に一度に 1 つの引数のみを処理して新しい関数を返す方法であることを思い出してください。それを念頭に置いて、最初の 2 つを指定された関数に適用します。一致するパターンは 1 つだけなので、新しい関数ができました。これを「curry」と呼びましょう。

curry n = n * pow 1 n

これで、対応する pow 関数の「内部」バージョンができたことに注意してください。そうすることで、また、1 つのパターンが一致します。この内側のカリー化された関数を「rice」と呼びましょう:

rice n = n * pow 0 n

もう 1 つ、「エビ」ですが、今回は別のパターンが一致します。

shrimp n = 1

再帰はここで終了したため、次のようになります。

rice n = n * 1
curry n = n * (n * 1)

次に、元の 2 番目の 2 をpow 2 2新しいcurry関数で使用します。

curry 2 = 2 * (2 * 1)

もちろん4です。

SML がこのようにカリー化された関数に名前を付けているとは思えませんが、これが概念を理解するのに役立つことを願っています。お腹がすいたとしても、私は責任を負いません。

于 2011-02-09T03:11:09.760 に答える
1
2*pow(1)2 =2*(2*pow(0)2)2 

ここで展開pow 12 * pow 0 2て 2 をそのままにしておきます。これは間違っています。pow 1単独では に展開され(fn n => n * pow 0 2)ますが、2 番目の引数にも適用する場合にのみ になり2 * pow 0 2ます。したがって、上記は次のようになります。

2*pow(1)2 =2*(2*pow(0)2)

を適用するpow 0 2と 1 になるので、最終結果は次のようになります。

2*pow(1)2 = 2*(2*pow(0)2) = 2*(2*1) = 4
于 2011-02-09T02:59:12.830 に答える