11

関数アプリケーションがhaskellのカリングでどのように動作するかを理解するのに問題があります。 私は、次の機能を持っている場合:ハスケルドル演算子アプリケーション

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

私は部分的にこの機能を適用するために、私は(a -> b)機能($の最初の引数)を提供する必要があることを理解しています。

なぜ最初に値を適用することができますか(逆引き)?

($ 0) :: Num a => (a -> b) -> b 

私はここで何が欠けていますか?

答えて

13

($)がオペレータである必要があり(\x -> ($) x 0)のように第二引数を適用します。このルールの唯一の例外は順番に、(-)あること

(x $) = (\y -> x $ y) = ($) x 
($ x) = (\y -> y $ x) = flip ($) x 

注:Haskellで、任意のオペレータは、左部((x $)など)または右セクション(($ x)など)に書き込むことができます便利な負の数書くこと:あなたが簡潔(\y -> y - x)を書きたい場合には

\x -> (x-) :: Num a => a -> a -> a -- equivalent to \x -> (-) x 
\x -> (-x) :: Num a => a -> a  -- equivalent to \x -> negate x 

を、あなたはsubtract使用することができます。

\x -> subtract x :: Num a => a -> a -> a -- equivalent to \x -> flip (-) x 
+0

ありがとう、これは、このように動作している理由を説明します。これらの定義は言語の特徴ですか、あるいはソースのどこかにありますか? – Rumca

+2

@Rumcaソースではありませんが、(x $)と($ x)はセクションであり、その説明は[2010 haskell report](http://www.haskell.org/onlinereport/haskell2010/)にあります。 )を参照してください(http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-300003.5)。 – Davorak

+0

言語は[Haskell 2010 Report](http://www.haskell.org/onlinereport/haskell2010/)に記載されています。 –

4

($ 0)≡≡(\x -> x $ 0)(\x -> ($) x 0)

($) :: (a -> b) -> a -> b)あれば、我々は我々が:: Num a => (a -> b) -> b

2

演算子の挿入表記を関数と混同しています。ここで

> :t (($) (+1)) 
(($) (+1)) :: Num b => b -> b 

よりよく理解するため$との表現のいくつかの形態は、以下のとおりです。

$ bの=>($)AB

($ B)=>フリップ($)B =>(\ BA - >($)AB)=> B \ - >($)AB

($)=>($)、A => \ B - >($)AB

+0

-1この質問の内容とその理由をしっかりと理解している人でも、私はこの解答を理解できません。ハスケルを知らない人はどのようにこのことをよく理解しているでしょうか?演算子と関数の違いについては何の説明もありません。 '$ b => flip($)b => \ a - >($)a'は有効な構文でもありません。 (編集:もう少し担当者がいれば、それは-1になるだろう) –

1

Haskellの構文では、英数字の名前は句読点の名前と区別されることにも注意してください。

英数字の機能foo1 a bはデフォルトで接頭辞ですが、バックティックを追加すると後書きになります:a `foo` b

$または<*>などの句読点-という名前の関数は、デフォルトでは中置で、あなたは括弧($)または(<*>)を追加する場合、接頭辞になります。これはラテンアルファベットに精通したプログラマーのためのシンタックスシュガーです。英数字の名前と句読点の名前の間には任意ですが有益な区別があります。

両方の種類の関数は単なる関数であり、C++やJavaの "演算子"に対して持っている特殊な意味規則はありません。これは、句読点付きの関数と英数字の名前付き関数で異なる、接頭辞/接尾辞とバッククォート/括弧の構文ルールです。