2011-10-21 23 views
0

私はOCAMLのこの課題に少し取り残されています。私は関数と値を別の関数にパラメータとして渡そうとしています。例えば、(fun x - > x + x)と3をパラメータとして取り込むtestという関数があります。機能テストは、出力6はずなので、3 + 3 = 6私が完了することによって、この類似した何かを達成することができます知っている:私は得るでしょう、私は入力、5をテストするときOCAML:let func a x =(a x);;の違いfunc a x =((fun a - > a)x);;

let func x = x + x;; 

let a = func;; 

let test a x = (a x);; 

この道を10

しかし、私はこれにステートメントを変更するとき、私はxに配置された値だけを取得します。どのようにして(fun a - > a)をxの値にするのですか?

let test a x = ((fun a -> a) x);;

答えて

4

fun a -> aは匿名ID機能である、それは常にそのパラメータを返します。あなたは言うことができる:

let id = fun a -> a;; 
id 3;; 
    => 3 
id (fun x -> x + x);; 
    => (fun x -> x + x) 

注意をご

let test a x = ((fun a -> a) x);; 

a第一および他の2つのa sが異なる変数であることを。最初のものは決して後で使用されることはありません。 ( - > A楽しいa)の値xに取るために私が手にするにはどうすればよい

let test a x = ((fun b -> b) x);; 

:あなたはと理解を容易にするために、この行を書き換えることができますか?

これは問題です。あなたはあなたのxを身元確認機能に送り、xを返しています。多くの場合と同様の形式で式を記述すると便利であるシンプルな例では関数型言語では

let func x = x + x;; 
let test a x = a x;; 
test func 3;; 
    => 6 
1

:何がやりたいことはあなたのa関数にxを供給し、それはあなたがあなたの最初の試みでやったことだですラムダ計算を実行し、手動で減量を行います(使用している減量に注意してください)。あなたはまだあなたの例の場合には、これはなるので

ラムダ計算の簡易版としてOCamlの構文を使用することができます。

let test a x = ((fun a -> a) x);; 
=> let test a x = ((fun b -> b) x);; (* Variable renamed (alpha equivalence) *) 
=> let test a y = ((fun b -> b) y);; (* Variable renamed (alpha equivalence) *) 

    let func x = x + x;; 

これらの手順のみを確認するのに役立つことに注意してください、私たちは後になること異なる名前を参照して、同じ名前の変数はありません。これらのステップは省略することができますが、私は個人的には一意の変数を使う方がはるかに優れています。

test func 5 
=> test (fun x -> x + x) 5 (* Variable func inserted (beta reduction) *) 
=> (fun a y -> ((fun b -> b) y) (fun x -> x + x) 5 (* Variable test inserted *) 
=> (fun y -> (fun b -> b) y) 5 (* Variable a inserted *) 
=> ((fun b -> b) 5 (* Variable y inserted *) 
=> 5 (* Variable b inserted *) 

最終結果は5です。これを最初に試みることは、非常に珍しくて難しいように見えますが、非常に速く簡単になります。このようなことを2,3回行うと、共通の機能パターンを理解し、プログラム構造を推論する上で、はるかに優れたものになります。

詳細については、this articleをご覧ください。

もう少し努力すれば、これも逆に働くことに注意してください。これは通常、コンパイラと同じ方向に行うほど役に立ちませんが。

関連する問題