40

Haskell初心者はこちら。Learn you a haskellを読んでいて、フリップ関数のこの定義に出くわしました。

flip' :: (a -> b -> c) -> (b -> a -> c)  
flip' f = g  
    where g x y = f y x

私が得られないのは、xとyはどこから来たのですか?つまり、シグニチャはflip'、それが関数(2つのパラメータを持つ)を受け取り、関数(ここでも2つのパラメータを持つ)を返す関数であることを示しています。

私がこの権利を理解しているなら、私が次のような関数を書くとき

foo :: (a -> b) -> a -> b
foo f x = f x   -- applies the function f on x

ただし、この場合、パラメーターを明示的に渡す[つまりx]ので、関数本体でパラメーターにアクセスできます。では、flip'なぜ関数はパラメーターxとyにアクセスできるのでしょうか。

4

5 に答える 5

43

hackage.haskell.orgの基本パッケージに含まれているプレリュードは、フリップ関数が見つかるすべてのHaskellファイルに暗黙のインポートで含まます。右側にある「ソース」をクリックすると、flipのソースコードが表示されます。

flip         :: (a -> b -> c) -> b -> a -> c
flip f x y   =  f y x

where句では、ローカル定義、x=10またはを使用できますy="bla"。トップレベルの場合と同じ構文を使用して、関数をローカルで定義することもできます。add x y = x + y

以下の同等の定式化では、私は置換を行いますg = f y x

flip         :: (a -> b -> c) -> b -> a -> c
flip f x y   =  g
  where
    g = f y x

現在、gはパラメータを取りません。しかし、gも定義すると、次のg a b = f b aようになります。

flip         :: (a -> b -> c) -> b -> a -> c
flip f x y   =  g x y
  where
    g a b = f b a

いいえ、少し代数的なキャンセルを行うことはできません(数学のクラスの代数のように考えると、かなり安全になります)。焦点を当てる:

flip f x y   =  g x y

次の場合は、両側のyをキャンセルします。

flip f x   =  g x

xをキャンセルします。

flip f   =  g

そして今、それを完全な表現に戻すために:

flip     :: (a -> b -> c) -> b -> a -> c
flip f   =  g
  where
    g a b = f b a

最後の表面的なステップとして、関数を引数名に戻すための置換aを行うことができます。xby

flip     :: (a -> b -> c) -> b -> a -> c
flip f   =  g
  where
    g x y = f y x

ご覧のとおり、このフリップの定義は少し丸みを帯びており、プレリュードで開始するのは単純で、私が好む定義です。whereそれがどのように機能し、Haskellコードの少し代数的な操作を行う方法を説明するのに役立つことを願っています。

于 2013-01-18T11:22:23.890 に答える
17

flip'xアクセスしませんy。引数を受け取り、f式に評価されますg。いいえx、またはy見えません。

ただし、gそれ自体は関数であり、のwhere節の補助方程式で定義されflip'ます。

g x y = f y xのようなトップレベルの方程式であるかのように正確に読み取ることができますflip'。したがって、2つの引数とgの関数です。にアクセスできるのは、ではなく、です。これらの引数の値は、が適用されるまで存在しません。適用されるまでは、関数が返されるまで存在しません(存在する場合)。xygxyflip'gflip'g

の節でg定義されることについて特別なことは、の引数にアクセスできることです。これは、の観点から定義する方法です。whereflip'flip'gf

したがって、flip'が呼び出されると、関数を受け取りますf。の特定の呼び出しごとにflip'、新しい関数を作成しますggは2つの引数を受け取り、呼び出されるxy、それはまだ発生していません。flip'その後、結果として返さgれます。

于 2013-01-18T10:52:36.830 に答える
1

のタイプを見つけましょうg

私たちはフリップタイプを知っています:(a -> b -> c) -> (b -> a -> c)

fしたがって、タイプを推測できます。(a -> b -> c)

この定義はg

g x y = f y x

右側からそれを推測しy :: aますx :: b

したがって、g :: b -> a -> c

'where'句なしで定義を書き直すことができることに注意してください。

flip' f = g where g x y = f y x
-> flip' f a b = g a b where g a b = f b a
-> flip' f a b = f b a
于 2013-01-18T10:50:23.897 に答える
1

簡単に言うと、whereブロックで関数を定義することもできます。したがって、変数xyは、の正式なパラメータにすぎません。そのため、 :gでアクセスできます。正式なパラメータとを定義し、は何をするかの定義です。最後に、その定義はから返されます。g x y = f y xg x yxyf y xgflip f = g

于 2017-01-01T04:50:28.923 に答える
1

ghciで理解して説明する簡単な例は次のとおりです。

Prelude> sub x y = x - y
Prelude> sub 3 1
2
Prelude> flip sub 3 1
-2
于 2020-10-05T07:52:55.037 に答える