Где полезен оператор Idris ==?

Как новичок в программировании, управляемом типами, мне интересно использовать оператор ==. Примеры демонстрируют, что недостаточно доказать равенство между двумя значениями определенного типа, и для конкретных типов данных вводятся специальные типы проверки на равенство. В таком случае, где == вообще полезен?


person Attila Karoly    schedule 22.07.2017    source источник
comment
определенного типа, означающего, что именно? Похоже, вы знаете, что он используется для других типов, так что отвечает ли это на ваш собственный вопрос?   -  person OneCricketeer    schedule 22.07.2017
comment
Он используется для сравнения чисел Nat в одном из примеров, и я нахожу это озадачивающим, что оператора == недостаточно, чтобы доказать, что они равны. Чтобы быть более конкретным, позвольте мне сказать так: для каких типов оператора == достаточно, чтобы доказать равенство?   -  person Attila Karoly    schedule 22.07.2017
comment
Ну, на самом деле я не знаю Идриса, но я воображаю простые примитивы чисел и логических значений. Возможно, строки (при условии, что это не похоже на Java)   -  person OneCricketeer    schedule 22.07.2017


Ответы (2)


Вам по-прежнему нужно старое доброе равенство, потому что иногда вы ничего не можете доказать. Иногда даже не нужно доказывать. Рассмотрим следующий пример:

countEquals : Eq a => a -> List a -> Nat
countEquals x = length . filter (== x) 

Возможно, вы захотите просто подсчитать количество одинаковых элементов, чтобы показать пользователю некоторую статистику. Другой пример: тесты. Да, даже со строгой системой типов и зависимыми типами вы можете захотеть выполнить старые добрые модульные тесты. Итак, вы хотите проверить ожидания, и это довольно удобно делать с помощью оператора (==).

Я не буду писать полный список случаев, когда вам может понадобиться (==). Оператора равенства недостаточно для доказательства, но вам не всегда нужны доказательства.

person Shersh    schedule 22.07.2017

(==) (как единственная составляющая функция интерфейса Eq) является функцией от типа T до Bool и подходит для рассуждений по уравнениям. Принимая во внимание, что x = y (где x : T и y : T) АКА «интенсиональное равенство» само по себе является типом и, следовательно, предложением. Вы можете и часто захотите переключаться между двумя разными способами выражения равенства для определенного типа.

x == y = True также является предложением и часто является промежуточным шагом между рассуждениями о (==) и рассуждениями о =.

Точные отношения между двумя типами равенства довольно сложны, и вы можете прочитать https://github.com/pdorrell/learning-idris/blob/9d3454a77f6e21cd476bd17c0bfd2a8a41f382b7/finished/EqFromEquality.idr для моей собственной попытки понять некоторые его аспекты. (Следует отметить, что даже если индуктивно определенный тип будет иметь определяемое интенсиональное равенство, вам все равно придется пройти через несколько обручей, чтобы доказать это, и еще несколько обручей, чтобы определить соответствующую реализацию Eq.)

Вот один из удобных фрагментов кода:

-- for rel x y, provide both the computed value, and the proposition that it is equal to the value (as a dependent pair)
has_value_dpair : (rel : t -> t -> Bool) -> (x : t) -> (y : t) -> (value: Bool ** rel x y = value)
has_value_dpair rel x y = (rel x y ** Refl)

Вы можете использовать его с конструкцией with, когда у вас есть значение, возвращаемое из rel x y, и вы хотите обосновать предложение rel x y = True или rel x y = Falserel — это некоторая функция, которая может представлять понятие равенства между x и y).

(В этом ответе я предполагаю случай, когда (==) соответствует =, но вы можете полностью определить функцию (==), которая не соответствует =, например, при определении Setoid. Так что это еще одна причина для используйте (==) вместо =.)

person Philip Dorrell    schedule 23.07.2017