2017-01-02 12 views
2

に関数適用演算子を理解する上でコードはHaskellの

map ($ 3) [(4+), (10*), (^2), sqrt] 

のこのHaskellの作品は、私は$が右に最低の優先順位、したがって表現を持っていることを知っている出力に

[7.0,30.0,9.0,1.7320508075688772] 

を与える手助けが必要です$の値は一緒に評価されます。しかし、私が理解できないことは、($ 3)が関数としてどのように動作するかです(Mapは関数とリストをパラメータとして取るためです)。

($) :: (a -> b) -> a -> b 
f $ x = f x 

($ 3)\f -> (f $ 3)の省略形です:リスト内の各機能が($)が実際に関数であることを覚えておいてください。3.

答えて

4

に適用された理由を私は理解していません。そしてそのタイプ?まあ:

3  ::     Double -- for sake of simplicity 
($) :: (a  -> b) -> a  -> b 
($ 3) :: (Double -> b)   -> b 

ので($ 3)Doubleから何かに関数を取り、3にその関数を適用する機能です。我々はmapを使用している場合今、私たちはで終わる:

map ($ 3) [(4+), (10*), (^2), sqrt] 
= [($ 3) (4+), ($ 3) (10*), ($ 3)(^2), ($ 3) sqrt] 
= [(4+) $ 3, (10*) $ 3, (^2) $ 3, sqrt $ 3] 
= [4 + 3, 10 * 3, 3^2, sqrt 3] 
= [7, 30, 9, sqrt 3] 
+0

ドルが関数である場合、関数部分をパラメータに適用するのではなく、パラメータに適用するべきではありません。私は何かが間違っていることをかなり確信しています:)ただ私が間違っているものを理解することができません – Ashwin

+0

@Ashwin err、何ですか? 「関数をパラメーターに適用するのではなく、パラメーターに適用するべきではない」という意味はどうですか? – Zeta

+0

私はそれが別の方法であるべきではないことを意味します。 (4+)は、パラメータとして3を取る代わりに3を取るべきです(4+)。 – Ashwin

3

てみましょう最初の($)の型シグネチャを確認してください。

ghci>> :t ($) 
($) :: (a -> b) -> a -> b 

と定義:

($) f x = f x 

または:

f $ x = f x 

以上ではセクションがあり、部分適用バージョン($)を作成し、2番目の引数(タイプa)を3として設定しました。さて、我々は3がタイプNum a => aを持っていることを知っているので、私たちの部分的なアプリケーションのタイプシグネチャはNum a => (a -> b) -> bでなければなりません。

次に、($ 3)の引数となる、それぞれの関数を見てみましょう。期待どおり、それらは関数であり、実際には型のNum a -> a -> aが必要以上に制約されていることが分かりました。ただ、明確にするために、我々は一つのアプリケーションが必要となるかを見ることができます:

我々は節なしで書き換えることができます
($3) (4+) 

:それはどのように上記の関数定義からかなり明確だその時点で

($) (4+) 3 

をアプリケーションは続行されます。

最後の混乱している部分は、リストのタイプと同じである可能性があります。($3) (4+)は、repl内で7.0ではなく、7と評価されます。リストが均質であり、リスト内の関数の1つであるsqrtが浮動値を受け入れて返すことに気がついた場合、この型はすべてのアプリケーションに適用されます。

+0

あなたは$ 3(4+)3(4+)を書き直しましたか? – Ashwin

+2

@Ashwin: '($ 3)= \ f - > f $ 3'、または接頭辞表記の' \ f - >($)f 3'です。 'f'を'(4+) 'で置き換えます。 – Zeta