私はこのコードを取ることになっています:
f x y z = x^3 - g (x + g (y - g z) + g (z^2))
where g x = 2*x^2 + 10*x + 1
そして、どこにも書き直さないでください(またはさせてください)。
Lambda関数で記述することを意味します(\ x-> ...)
HaskellでLambda関数を再利用しようとしています。何か案は?
私はこのコードを取ることになっています:
f x y z = x^3 - g (x + g (y - g z) + g (z^2))
where g x = 2*x^2 + 10*x + 1
そして、どこにも書き直さないでください(またはさせてください)。
Lambda関数で記述することを意味します(\ x-> ...)
HaskellでLambda関数を再利用しようとしています。何か案は?
let
bravitが示唆しているように、次の方法でラムダを使用して非再帰的に書き直すことができます。
let x = A in B ==> (\x -> B) A
ここx
で、は変数でありA
、B
は式です。
何かを再利用するには、それを何かの議論にすることができます。
ハンマーとブラビットのヒントを拡張するために、ソリューションには1つのラムダだけでなく、2つのラムダが必要になります。1つはのように見え、もう1つはg
後半のように見えます。f
その意図は、ブラビットが示唆するものだと思います。
Smartypantsの法則に従う回避策はg
、case
;)と拘束力があります。
ラムダ計算の使用g
は(\x -> 2*x^2 + 10*x + 1)
したがって、gをそれで置き換える必要がありますf x y z = x^3 - g (x + g (y - g z) + g (z^2))
$> echo "f x y z = x^3 - g (x + g (y - g z) + g (z^2))" | sed -r -e 's/g/(\\x -> 2*x^2 + 10*x + 1)/g'
f x y z = x^3 - (\x -> 2*x^2 + 10*x + 1) (x + (\x -> 2*x^2 + 10*x + 1) (y - (\x -> 2*x^2 + 10*x + 1) z) + (\x -> 2*x^2 + 10*x + 1) (z^2))
冗談です、ごめんなさい。
その質問は私にとってちょっと好奇心が強くて面白いようです。だから、私はラムダ計算が何であるかを理解し、答えを見つけてそれをOPに見せたいと思っています(すべてのヒントはすでに実際に示されています、ネタバレ注意)。
まず、再定義してみましょうf
:
λ> let f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2)))
f ::
(Integer -> Integer) -> Integer -> Integer -> Integer -> Integer
つまり、関数と3つの数値を取得して、答えを返す関数があります。curringを使用して、次g
のようにここに定義を追加できf_new = f g
ます。
λ> let f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2))) (\x -> 2*x^2 + 10*x + 1)
f :: Integer -> Integer -> Integer -> Integer
終わったね。それを確認しましょう:
λ> f 0 0 0
-13
答えは正しいです。
UPD:
これらの例let
では、インタプリタで関数を宣言する方法にすぎないため、最終的な答えは次のとおりです。
f :: Num a => a -> a -> a -> a
f = (\g x y z -> x^3 - g(x + g(y - g z) + g(z^2))) (\x -> 2*x^2 + 10*x + 1)