5

ghci の次の関数定義を検討してください。

let myF = sin . cos . sum 

どこ、 。2 つの関数の合成 (右結合) を表します。これは私が呼び出すことができます

myF [3.14, 3.14]

そして、それは私に望ましい結果をもたらします。どうやら、リスト [3.14, 3.14] を関数「sum」に渡し、その「結果」を cos などに渡します。ただし、これをインタープリターで行うと

let myF y = sin . cos . sum y 

また

let myF y = sin . cos (sum y) 

それから私はトラブルに遭遇します。これを次のように変更すると、望ましい結果が得られます。

let myF y = sin . cos $ sum y 

また

let myF y = sin . cos . sum $ y 

(.) の型は、'sum y' も関数であるため、次の形式に問題がないことを示唆しています (そうではありませんか? 結局、Haskell ではすべてが関数なのでしょうか?)。

let myF y = sin . cos . sum y -- this should work?

さらに興味深いのは、2 つ (または多数) の引数 (リスト [3.14, 3.14] を 2 つの引数 x と y として渡すことを考えてください) で動作させることができることです。次のように記述する必要があります。

let (myF x) y = (sin . cos . (+ x)) y 
myF 3.14 3.14 -- it works! 
let myF = sin . cos . (+) 
myF 3.14 3.14 -- -- Doesn't work!

HaskellWiki には、「PointFree」フォームhttp://www.haskell.org/haskellwiki/Pointfreeと呼ばれるこのフォームに関するいくつかの議論があります。この記事を読んで、この形式は 2 つのラムダ式の合成とは異なるのではないかと疑っています。これらのスタイルの両方を区切る線を引こうとすると、混乱してしまいます。

4

3 に答える 3

10

種類を見てみましょう。sinと私たちはcos持っています:

cos, sin :: Floating a => a -> a

の場合sum:

sum :: Num a => [a] -> a

今、sum yそれを

sum y :: Num a => a

これは値であり、関数ではありません (引数なしで関数に名前を付けることができますが、これは非常にトリッキーであり、関数にも名前を付ける必要があり() -> aます -これについてどこかで議論がありましたが、今はリンクが見つかりません-コナルはそれについて話しました)。

いずれにせよ、両方が型and (署名は)を持つことを期待しており、このスタイルでは記述できないcos . sum yため、試してもうまくいきません。そのため、括弧またはを含める必要があります。.a -> bb -> c(b -> c) -> (a -> b) -> (a -> c)sum y$

ポイントフリースタイルに関しては、単純な翻訳レシピは次のとおりです。

  • 関数を取得し、関数の最後の引数を関数適用で区切られた式の最後に移動します。たとえば、最後mysum x y = x + yに持っているがy、今は削除できない場合です。代わりに、動作するように書き換えmysum x y = (x +) yます。
  • その引数を削除します。私たちの場合にはmysum x = (x +)
  • 引数がなくなるまで繰り返します。ここmysum = (+)

(使用する必要があるより複雑なケースなどのために、簡単な例を選択しましflipた)

于 2011-08-02T14:01:38.737 に答える
7

いいえ、sum y関数ではありません。ちょうどそうです、それは数sum [1, 2, 3]です。したがって、関数合成演算子を使用できないことは完全に理にかなっています(.)

Haskellのすべてが関数であるわけではありません。

于 2011-08-02T13:56:52.603 に答える
4

必須の不可解な答えは次のとおりです。(スペース) は、.

Haskell のほとんどの空白は、非常に固定性が高い$(「適用」機能) と考えることができます。w x . y z基本的に同じです(w $ x) . (y $ z)

初めて学習するときは、(スペース)についても学習する必要が$あります。また、言語のセマンティクスが、(一見すると) 直感的に見えない方法で暗黙的に括弧を付ける方法を理解していることを確認してください。.

于 2011-08-03T08:11:55.437 に答える