1

プレリュードから:

foldl1:リストの最初の2つの項目を取得し、それらに関数を適用してから、この結果と3番目の引数を関数にフィードします。

なぜこのようなものを書くことができないのですか?

foldl1 (==) [6, 6, 6]
foldl1 (\x y -> x == y) [6, 6, 6]
4

4 に答える 4

5

リストのすべての要素が等しいかどうかを確認したい場合、簡単な解決策は次のとおりです。

allEqual [] = True --(edit: this case is not necessary as pointed out by sepp2k)
allEqual xs = all (== head xs) xs

誰かがこれを行うためのよりエレガントな方法を書くでしょう、私は確信しています、しかしこれは実用的です。

編集:提案をしてくれたsepp2kに感謝します。

于 2011-02-06T00:17:36.993 に答える
2

編集:アンタルは私の推論が間違っていたと指摘します。これが本当の理由を与えるコメントの関連部分です(私はこれを逐語的に取るのは気分が悪いですが、この答えは受け入れられたので削除できません):

これが機能しない理由は、のタイプはfoldl1です(a -> a -> a) -> [a] -> aが、のタイプは(==)ですNum a => a -> a -> BoolBoolはではないため、Numタイプ(==)が一致しないa -> a -> aため、の適用foldl1は拒否されます。それが受け入れられた場合、あなたはあなたがやろうとしていた状況になってしまうでしょうTrue == 6、しかし型システムはあなたがそもそもそこまで到達することは決してありません。

元の答え(後の推論は正しくありません):

==2Int秒かかり、を返しますBool。最初の反復の後、サンプルリストはになり[True, 6]ます。True次に、どちらが失敗したかを比較しようとし6ます。

于 2011-02-06T00:11:42.350 に答える
1

別のバージョンは次のとおりです。

allEqual xs = and $ zipWith (==) xs (tail xs)
于 2011-02-06T18:29:27.503 に答える
0

フォールドを使用する場合は、次の変更をお勧めします。

allEqual xs = foldr (\x acc -> x == head xs && acc) True xs

allこれは、すでに提案されているアプローチと非常によく似ています。これとallアプローチの両方が無限のリストで機能することに注意してください(答えがである限りFalse)。

非常に長い有限リストの場合、非常にまれなケースですが、厳密な左折りからパフォーマンスが向上する場合があります。

allEqual xs = foldl' (\acc x -> acc && x == head xs) True xs

ただし、(この実装では)に等しい数の折り畳みステップしか実行しないため、この問題には一般的に正しい折り畳みの方が適していますlength $ takeWhile (== head xs) xs。左の折り目はlength xs毎回折り畳みステップを実行します。

于 2011-02-06T02:16:27.890 に答える