私が非常に便利で直感的だと思った折り目について考える方法があります(私はおそらくこれをどこかで読んでいます)。これは最も効率的な解決策にはならないかもしれないことに注意してください、しかしここでの私の懸念は明確さです。
foldは、リストから値を作成する関数とは考えないでください。代わりに、リストの要素間に演算子を挿入する方法と考えてください。そうすると、foldはリストを式に変換する方法になります。したがって、たとえば、次のようになります。
foldr op I [A,..,Z]
次の拡張を生成します。
A op .. op Z op I
あなたがその考えをあなたの問題に適用するならば、あなたがする必要があるのは何をすべきかを自問することです、そして私はあなたがA .. Zが真である場合にのみ真になることを確実にすることです?ヒントとして、私は通常、opに関する単位元です(0が加算のように、式を変更しない値)。
論理から、and(&&)は、そのすべてのオペランドが真である場合にのみ真であることがわかります。同様に、Trueは&&に関する単位元です。そうは言っても、拡張は次のようになります。
A && .. && Z && True
したがって、フォールドは次のようになります。
foldr (&&) True [A,..,Z]
つまり、関数は次のようになります。
boolTrueList x = foldr (&&) True x
または、よりポイントフリーのスタイルで:
boolTrueList = foldr (&&) True
反復を回避するために高階関数を使用するだけでは十分ではありません。反復的な考え方を回避する必要があります。「この時点で、この値は伝播する」ではなく、自由形式の表現で考えてください。多くの場合、反復は制限のない式を生成するための低レベルの方法であり、私たちの言語がこれを強制したため、式で考えることができる言語がある場合でも、私たちの考え方はしばしばそれに固執していますレベル。