web-dev-qa-db-ja.com

Haskell関数の構成(。)および関数の適用($)イディオム:正しい使用法

私はReal World Haskellを読んでおり、終わりに近づいていますが、スタイルの問題が(.)および($)演算子。

他の関数の合成である関数を書くとき、次のように書きます:

f = g . h

しかし、これらの関数の最後に何かを適用すると、次のようになります。

k = a $ b $ c $ value

しかし、この本は次のように書きます。

k = a . b . c $ value

今、私にとっては機能的に同等に見えますが、私の目にはまったく同じことをします。しかし、私が見れば見るほど、本がそうするように人々が彼らの機能を書いているのを見ます:(.)最初に、最後にのみ($)ロットを評価するために値を追加します(多くのドル構成でそれを行う人はいません)。

書籍の方法を使用する理由は、すべて($)記号?または、ここに私が得ていないベストプラクティスがありますか?それとも余分なもので、私はそれをまったく心配するべきではありませんか?

121

私は当局からこれに答えることができると思います。

すべての($)記号を使用するよりもはるかに優れた、書籍の方法を使用する理由はありますか?

特別な理由はありません。ブライアンと私はどちらも回線ノイズを減らすことを好みます。 .$よりも静かです。その結果、本はf . g . h $ x構文を使用します。

143
Don Stewart

これらは実際に同等です。$演算子は本質的に何もしないことに注意してください。 f $ xf xと評価されます。 $の目的は、その固定性の振る舞いです:右結合および最小の優先順位。 $を削除し、中置優先順位の代わりにグループ化に括弧を使用すると、コードスニペットは次のようになります。

k = a (b (c (value)))

そして

k = (a . b . c) value

.バージョンより$バージョンを好む理由は、上記の非常に括弧で囲まれたバージョンよりも両方を好む理由と同じです:美的魅力。

ただし、括弧の代わりに中置演算子を使用することは、LISPに似ている可能性を避けるための潜在的な衝動に基づいているのではないかと思う人もいるかもしれません(冗談です...思いますか?)。

52
C. A. McCann

f . g $ xに追加すると、f . gは意味のある構文単位になります。

一方、f $ g $ xでは、f $ gは意味のある単位ではありません。 $のチェーンは、間違いなくより命令的です-最初gの結果を取得しますxthen do fに、-then do fooに、thenなど。

一方、.のチェーンはほぼ間違いなく宣言的であり、ある意味ではデータフロー中心のビューに近い-一連の関数を構成し、最終的にそれらを何かに適用します。

37
sclv

私にとっては、答えは(a)きちんとしたものだと思います ドンは言った ; (b)コードを編集しているときに、関数がポイントフリースタイルになることがあります。すべてを変更するのではなく、最後の$を削除するだけです。確かにマイナーな点ですが、素晴らしい点です。

18

this haskell-cafe thread でこの質問の興味深い議論があります。どうやら$の正しい結合性は "単なる単純な誤り" であり、f . g . h $ xよりもf $ g $ h $ xを選択することがサイドサイドの1つの方法であるという少数の視点があります。問題をステップします。

13
Travis Brown

それはただのスタイルの問題です。しかし、本のやり方は私にとってより理にかなっています。すべての関数を構成し、値に適用します。

あなたのメソッドは奇妙に見え、最後の$は不要です。

しかし、それは本当に重要ではありません。 Haskellでは、通常、同じことを行うための多くの正しい方法があります。

3
Zifre

これは非常に古い質問であると思いますが、これについては言及されていない別の理由があると思います。

新しいポイントフリー関数を宣言している場合f . g . h、渡した値が自動的に適用されます。ただし、f $ g $ h、 うまくいかないだろう。

著者が作曲方法を好む理由は、関数を構築する良い習慣につながるからだと思います。

0
hackeryarn