空のリストの「and」がtrueを返すのはなぜですか?空のリストがTrueを保持していることを意味しますか? 申し訳ありませんが、これを正しく読んで理解できないので、修正してください。ありがとう。
Prelude> and []
True
Prelude> or []
False
&&
数学では、||
、+
、 、 などの 2 項演算について、恒等*
を持つものとして話すと便利なことがよくあります。ID は、次のプロパティが一般的な二項演算に対して保持されるような値です。e
<>
e <> x = x
x <> e = x
上記の演算子の場合、それらは可換x <> y = y <> x
であり、すべてのx
およびについて意味するためy
、上記のプロパティの 1 つだけをチェックする必要があります。の場合and
、問題の二項演算子は&&
でありor
、二項演算子の場合は||
です。これらの操作のCayley テーブルを作成すると、次のようになります。
&& | False | True
------+-------+------
False | False | False
True | False | True
|| | False | True
------+-------+------
False | False | True
True | True | True
ご覧のとおり、とがある&&
場合、答えは常に の 2 番目の引数になります。for 、およびがある場合、答えは常に 2 番目の引数であるため、それぞれの最初の引数は、これらの演算子の下の恒等要素でなければなりません。簡単に言えば:True && False
True && True
&&
||
False || False
False || True
True && x = x
x && True = x
False || x = x
x || False = x
したがって、演算子を実行する要素がない場合の好ましい答えは、各操作の ID 要素です。
+
との恒等要素について考えることも役立つかもしれません。*
それぞれ0
と1
です。
x + 0 = x = 0 + x
x * 1 = x = 1 * x
これを、リスト連結 ( with )、タイプの関数の関数合成 ( with ) などの操作に拡張すること++
も[]
できます。これはパターンのように見え始めているので、これは既に Haskell にあるのかと尋ねるかもしれませんが、実際にそうなっています。モジュールは、このパターンを抽象化する型クラスを定義します。その最小限の定義は次のとおりです。a -> a
(.)
id
Data.Monoid
Monoid
class Monoid a where
mempty :: a -- The identity
mappend :: a -> a -> a -- The binary operator
また、使いやすさのために別名も付けmappend
られ<>
ます (一般的な二項演算子として上で選択したのは偶然ではありません)。そのモジュールを見て、その定義をいじってみることをお勧めします。ソースコードは非常に読みやすく、啓発的です。
優れた回答ですが、より直感的な扱いを提供する価値があると思います。ただし、代わりに をand :: [Bool] -> Bool
見てみましょうall :: (a -> Bool) -> [Bool] -> Bool
。このように考えることができますall
。リスト要素に関する仮説として述語 (a -> Bool
引数) を想像してください。次に、リストに仮説に対する反例が少なくとも 1 つ含まれている場合にのみ、を返します。リストが空の場合、反例がないため、自明に確認されます。all
False
に戻すには、とが相互定義可能and
であることに注意してください。がある場合は、次のように定義できます。and
all
and
all
all :: (a -> Bool) -> [a] -> Bool
all pred = and . map pred
逆に、すでに を持っている場合は、そこからall
定義できます。and
and :: [Bool] -> Bool
and = all id
@bheklilrの回答に加えて、モノイドはタプル(M,e,<>)
であり、M
はオブジェクト(型と考えることができます)でe
あり、オブジェクトのポイントM
(e : M
- 型の要素)で<>
あり、二項演算であることを思い出してください。は連想的でありe
、アイデンティティとして次のものを持っています:
<> : M -> M -> M
e <> x = x
x <> e = x
(x <> y) <> z = x <> (y <> z)
いくつかのモノイド間にはモノイド準同型があります。自由なモノイドが 1 つあります。このモノイドから他のモノイドへの準同型があります。このような自由なモノイドはリストです:([a], [], ++)
他のモノイドにマップできます。例えば:
([Int], [], ++) => (Int, 0, +)
([Int], [], ++) => (Int, 1, *)
([Bool], [], ++) => (Bool, True, &&)
([Bool], [], ++) => (Bool, False, ||)
次にsum
、product
、and
、or
はそれぞれのモノイド準同型であり、型[Int]
およびの要素をマッピングし[Bool]
ます。モノイド準同型の定義により、モノイドのマッピングh
は、任意のリストx++y
がポイントにマッピングされるように実行されます。h(x ++ y) == (h x) <> (h y)
たとえば、and (x++[]) == (and x) && (and [])
. 後者の例から、 since x++[] == x
、 so (and x) && (and []) == and x
、 したがってand []
が の恒等要素にマップされることが明らかになり(Bool, True, &&)
ます。
True
とについて考える 1 つの方法は、によって順序付けられたラティスFalse
の要素です。これは、このラティスの 2 項の「満たす」(最大の下限) および「結合」(最小の上限) 操作と見なすことができます。同様に、とは、一般的な有限結合操作と有限結合操作です。とは? の最大の下限です。しかし、は (漠然と) のすべての要素より小さいか等しいので、 の下限であり、(もちろん) 他の下限 (もう一方の ) よりも大きいので、False < True
&&
||
and
or
and []
[]
True
[]
[]
False
and [] = True
. 代数的な見方 (モノイドなどについて考える) は、順序論的な見方と完全に同等であることがわかりますが、順序論的な見方の方がより視覚的な直感を提供すると思います。
のロジックはand
、 であるリスト内の最初のエントリを見つけることですFalse
。エントリが見つからない場合、結果は になりTrue
ます。例えば:
and $ map even [2..]
無限リスト全体を反復するのではなく、 で停止し3
て戻りFalse
ます。False
空のリストには要素がないため、デフォルトでTrue
.
それor
も同様です: 最初のものを見つけようとしてTrue
停止します。それ以外の場合はFalse
.