質問

から プレリュード:

foldl1: :リストの最初の2つの項目を取り、関数を適用し、この結果と3番目の引数などで関数をフィードします。

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

foldl1 (==) [6, 6, 6]
foldl1 (\x y -> x == y) [6, 6, 6]
役に立ちましたか?

解決

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

これがうまくいかない理由は、 foldl1(a -> a -> a) -> [a] -> a, 、しかしのタイプ (==)Num a => a -> a -> Bool. 。以来 Bool ではありません Num, (==) タイプは一致しません a -> a -> a, 、したがって、の適用 foldl1 拒否されます。それが受け入れられた場合、あなたはあなたがやろうとしている状況になります True == 6, 、しかし、タイプシステムがそもそもそれを獲得することはありません。

元の答え(後者の推論が間違っている):

== 2つかかります Intsと返品a Bool. 。最初のイテレーションの後、あなたのサンプルリストはなります [True, 6]. 。その後、比較しようとします True6 失敗します。

他のヒント

リストのすべての要素が等しいかどうかを確認する場合、迅速な解決策は

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

誰かがこれを行うためのよりエレガントな方法を書くでしょう、と私は確信していますが、これはサービス可能です。

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

これが別のバージョンです:

allEqual xs = and $ zipWith (==) xs (tail xs)

折り目を使用したい場合は、この変更をお勧めします。

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 毎回折りたたみステップ。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top