10

空のリストの「and」がtrueを返すのはなぜですか?空のリストがTrueを保持していることを意味しますか? 申し訳ありませんが、これを正しく読んで理解できないので、修正してください。ありがとう。

Prelude> and []
True
Prelude> or []
False
4

7 に答える 7

38

&&数学では、||+、 、 などの 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 && FalseTrue && True&&||False || FalseFalse || True

True && x = x
x && True = x

False || x = x
x || False = x

したがって、演算子を実行する要素がない場合の好ましい答えは、各操作の ID 要素です。


+との恒等要素について考えることも役立つかもしれません。*それぞれ01です。

x + 0 = x = 0 + x
x * 1 = x = 1 * x

これを、リスト連結 ( with )、タイプの関数の関数合成 ( with ) などの操作に拡張すること++[]できます。これはパターンのように見え始めているので、これは既に Haskell にあるのかと尋ねるかもしれませんが、実際にそうなっています。モジュールは、このパターンを抽象化する型クラスを定義します。その最小限の定義は次のとおりです。a -> a(.)idData.MonoidMonoid

class Monoid a where
    mempty :: a                   -- The identity
    mappend :: a -> a -> a        -- The binary operator

また、使いやすさのために別名も付けmappendられ<>ます (一般的な二項演算子として上で選択したのは偶然ではありません)。そのモジュールを見て、その定義をいじってみることをお勧めします。ソースコードは非常に読みやすく、啓発的です。

于 2014-08-21T13:44:24.550 に答える
7

優れた回答ですが、より直感的な扱いを提供する価値があると思います。ただし、代わりに をand :: [Bool] -> Bool見てみましょうall :: (a -> Bool) -> [Bool] -> Bool。このように考えることができますall。リスト要素に関する仮説として述語 (a -> Bool引数) を想像してください。次に、リストに仮説に対する反例が少なくとも 1 つ含まれている場合にのみ、を返します。リストが空の場合、反例がないため、自明に確認されます。allFalse

に戻すには、とが相互定義可能andであることに注意してください。がある場合は、次のように定義できます。andallandall

all :: (a -> Bool) -> [a] -> Bool
all pred = and . map pred

逆に、すでに を持っている場合は、そこからall定義できます。and

and :: [Bool] -> Bool
and = all id
于 2014-08-21T17:41:09.813 に答える
5

@bheklilrの回答に加えて、モノイドはタプル(M,e,<>)であり、Mはオブジェクト(型と考えることができます)でeあり、オブジェクトのポイントMe : 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, ||)

次にsumproductandorはそれぞれのモノイド準同型であり、型[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, &&)ます。

于 2014-08-21T14:49:52.257 に答える
4

Trueとについて考える 1 つの方法は、によって順序付けられたラティスFalseの要素です。これは、このラティスの 2 項の「満たす」(最大の下限) および「結合」(最小の上限) 操作と見なすことができます。同様に、とは、一般的な有限結合操作と有限結合操作です。とは? の最大の下限です。しかし、は (漠然と) のすべての要素より小さいか等しいので、 の下限であり、(もちろん) 他の下限 (もう一方の ) よりも大きいので、False < True&&||andorand [][]True[][]Falseand [] = True. 代数的な見方 (モノイドなどについて考える) は、順序論的な見方と完全に同等であることがわかりますが、順序論的な見方の方がより視覚的な直感を提供すると思います。

于 2014-08-22T01:32:37.700 に答える
2

のロジックはand、 であるリスト内の最初のエントリを見つけることですFalse。エントリが見つからない場合、結果は になりTrueます。例えば:

and $ map even [2..]

無限リスト全体を反復するのではなく、 で停止し3て戻りFalseます。False空のリストには要素がないため、デフォルトでTrue.

それorも同様です: 最初のものを見つけようとしてTrue停止します。それ以外の場合はFalse.

于 2014-08-21T13:43:34.150 に答える