3

Haskell がセクション、複数の引数を取る関数、および部分的に適用される複数の関数の優先順位をどのように決定するかを説明してください。式全体が複数の引数を取る場合、どの部分関数にどの引数が適用されるかを理解するのが難しい場合があります。

ここに関数の例をいくつか示しますが、別の例の方がよりわかりやすいと思います。最初の 1 つは、「エフェクトを使用したアプリケーション プログラミング」の記事からの抜粋です。

sequence :: [IO a] → IO [a]
sequence [] = return []
sequence (c : cs) = return (:) `ap` c `ap` sequence cs

(.) (.)
(.) (.) (.)

そのような式をラムダ式の形式に変換するツールはありますか?

4

2 に答える 2

8

引数のない括弧内の演算子は、通常の識別子と同様に扱われます。したがって(+)addまったく同じように動作します。これは、プレフィックス形式で使用され、優先順位の問題が発生しないことを意味します。

それを念頭に置いて、次のように書くことを想像できます。

compose = (.)
compose compose compose

後者のバージョンは、 を使用した紛らわしいバージョンと同じ(.)です。関数の適用は右結合であるため、式は次のようになります。

(compose compose) compose

引数を持つ演算子セクションは、優先順位に関する限り、通常の識別子と同様に、(+ 1)または同様に動作します。(1 +)したがって、 を定義するnext = (+ 1)と、どちらも同じように動作します。

ポイントフリー コードに関する限り、ポイントフルパッケージには、ポイントフリー関数を受け取り、それを一連のラムダに変換しようとするコマンド ライン ツールがあります。この機能は、@unpl を使用して #haskell IRC チャネルの lambdabot から取得することもできます。

pointful を cabal でインストールして呼び出すことができます:

cabal install pointful
pointful
于 2013-06-21T19:44:24.117 に答える
3

のような関数アプリケーションの識別子のリストは、a b c dとして解析され(((a b) c) d)ます。括弧で囲まれた中置演算子(.)は、識別子のように扱われます。

として(.) (.) (.)解析し((.) (.)) (.)ます。

一般に、このような変数演算子

`functionname`

デフォルトでは左結合性があり、関数適用よりも優先順位が低くなりますが、これはinfixlorinfixr宣言で変更できます。関数はapデフォルトから変更されていないため、右辺はsequence次のようになります。

((return (:)) `ap` c) `ap` (sequence cs)

または同等に

ap (ap (return (:)) c) (sequence cs)
于 2013-06-21T20:02:34.260 に答える