4

たとえば、次のように書くことができます。

zipWith (,) [1,2,3] [4,5,6]

3リストをタプルする場合は、次のように記述できます。zipWith3(,,)[1,2,3] [4,5,6] [7,8,9]

使用することもできます zipWith4 (,,,) zipWith5(,,,,)

今、私は同じことをしたいのですが、代わりにコンマ演算子を追加します。のようにラムダを使用せずに、同じ簡潔な方法でそれを定義する方法はありますか?

zipWith3 (\a b c -> a + b + c) [1, 2, 3] [4, 5, 6] [7, 8, 9]

回答ありがとうございます。

4

4 に答える 4

12

の「ポイントフリー」スタイルのコードが必要なようです\a b c -> a + b + c。一般に\a b c -> a + b + c、バグを見つけた4週間後の方がはるかに読みやすいため、無料のコードを指す方が望ましい場合が多いことを知っておいてください。

ポイントフリープログラミングに関するwikiの記事があります(ソース)。

パッケージをインストールすることもpointfreeできます。これにより、コマンドラインでこれらの問題を解決できます。例えば、

$ポイントフリー'\xyz-> x + y + z'
((+)。)。(+)

ポイントフリーバージョンも同様です(疑問に思っ((+) .) . (+)た場合に備えて、x、y、zは「ポイント」であり、いいえ、これはジオメトリとは関係ありません)。必要に応じてその定義を使用できますが、ほとんどの人はあなたのコードを見て、その面白い見た目のASCIIアートが何をするのかわかりません。それらの半分は鉛筆と紙でそれを解決しますが、オリジナル\x y z -> x + y + zは目にはそれほど簡単ではありませんか?

ヒント:ポイントフリーコードが何をするのかを理解する必要がある場合は、次のタイプを確認してください。

プレリュード>:t((+)。)。(+)
((+)。)。(+)::(数値a)=> a-> a-> a-> a

または、pointfulパッケージをインストールすることもできます。これは、の逆ですpointfree

概要:ポイントフリープログラミングの世界へようこそ。コードが読めないように注意して進めてください。

于 2011-07-19T09:27:38.223 に答える
7

別のオプション:アプリケーションファンクター。実際、Control.Applicativeには、次のように使用できる新しいタイプ定義ZipListが含まれています(リストタイプのApplicativeにはいくつかの可能な定義があるため)。

import Control.Applicative 

getZipList $ (,,) <$> ZipList [1,2,3] <*> ZipList [4,5,6] <*> ZipList [7,8,9]

またはそのように((+)のカップルの場合):

getZipList $ (+) <$> ((+) <$> ZipList [1,2,3] <*> ZipList [4,5,6]) <*> ZipList [7,8,9]

この特定の問題に適用可能なファンクターを使用することはおそらくあまり意味がありませんが、それでも同様の種類のタスクを解決するための非常に強力な抽象化/メカニズムを提供するため、学ぶ価値があります(たとえば、zipWith3、zipWith4を取り除くことができます) ...など)。

于 2011-07-19T10:31:21.177 に答える
4

zipWith3をバイパスすると、次のことができます。

import Data.List (transpose)
map sum $ transpose [[1,2,3],[4,5,6],[7,8,9]]

zipWith3を使用すると、出力が最短のリストにカットされますが、これはカットされません。つまり、[[1,2]、[3]]の場合は[4,2]になります。

于 2011-07-19T12:27:37.710 に答える
2

I think you cannot write it without lamda. In fact zipWith3 requires as first parameter a function that takes 3 parameters, and (+) takes only two. So, you need to define "a plus function taking 3 parameters", that is exactly what your lambda does.

An alternative is:

foldr1 (zipWith (+)) [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]

I don't know if the above is terser than

zipWith3 (\a b c -> a + b + c) [1, 2, 3] [4, 5, 6] [7, 8, 9]
于 2011-07-19T10:20:46.220 に答える