Подтвердить что ты не робот

Понимание Haskell Bool, производящего Ord

Узнай, что у вас Haskell представлен тип Bool:

data Bool = False | True deriving (Ord)

Я не понимаю причину сравнения Bool.

> False `compare` True
LT
> True `compare` False
GT

Что было бы потеряно, если Bool не вышло из Ord?

4b9b3361

Ответ 1

Bool образует ограниченную решетку , где False внизу, а True - верхняя. Эта ограниченная решетка определяет (полный) порядок, где False действительно строго меньше True. (Они также являются единственными элементами этой решетки.)

Булевы операции and и or также могут рассматриваться как встречающиеся и объединенные соответственно в этой решетке. Встреча находит наибольшую нижнюю границу, и соединение находит наименьшую верхнюю границу. Это означает, что a && False = False - это то же самое, что и нижняя граница дна и всего остального - внизу, а a || True = True - это то же самое, что и верхняя граница вершины, а что-то верхняя. Таким образом, встреча и объединение, которые используют свойство упорядочения логических элементов, эквивалентны булевым операциям, с которыми вы знакомы.

Вы можете использовать min и max, чтобы показать это в Haskell:

False `min` True = False -- this is the greatest lower bound
False  &&   True = False -- so is this

False `max` True = True  -- this is the least upper bound
False  ||   True = True  -- so is this

Это показывает, что вы можете определить && и || только из производного экземпляра Ord:

(&&) = min
(||) = max

Обратите внимание, что эти определения не эквивалентны при наличии другого типа дна, поскольку (&&) и (||) являются короткозамкнутыми (нестрогими в второй аргумент, когда первый False или True, соответственно), а min и max не являются.

Кроме того, небольшая поправка: предложение deriving не говорит о том, что Bool "происходит от" Ord. Он инструктирует GHC получить экземпляр класса Ord для типа Bool.

* Более конкретно, дополненная распределительная решетка. Более конкретно, булева алгебра .

Ответ 2

Экземпляр Ord для Bool становится гораздо более важным, когда вам нужно сравнивать значения, содержащие Bool где-то внутри. Например, без него мы не сможем писать такие выражения, как:

[False,True] `compare` [False,True,False]

(3, False) < (3, True)

data Person = Person { name :: String, member :: Bool } deriving (Eq, Ord)

и др.

Ответ 3

Это потому, что дизайнеры Haskell допустили ошибку! Я никогда не видел учебника по математике, который упоминал порядок булевых. Просто так они могут быть, это не значит, что нужно. Некоторые из нас используют Haskell именно потому, что во многих случаях это запрещает/защищает нас от запутывающих/бессмысленных вещей, но не для этого.

instance Ord Bool приводит к тому, что a => b означает, что вы ожидаете a <= b в значении!

Ранее аргументы в пользу instance Ord Bool, где вы можете сделать больше типов сопоставимыми неявно. Продолжая эту аргументацию, некоторые могут захотеть сделать все типы сопоставимыми, а также иметь слабое динамическое типирование и вообще опустить классы классов. Но мы хотим, чтобы строгое написание точно запрещало то, что явно не правильно, и instance Ord Bool побеждает эту цель.

Что касается аргумента, что Bool - ограниченная решетка. В отличие от boolean: = {True, False}, то, что у нас есть в Haskell, есть Bool: = {True, False, bottom} больше не является ограниченной решеткой, так как ни True, ни False не являются элементами идентичности в представлении дна. Это связано с этими комментариями, обсуждающими && vs min и т.д.