2013-02-13 5 views
7

Хорошо известно, что экземпляры Monad должны соблюдать законы Монады. Возможно, менее известно, что экземпляры Functor должны следовать законам Functor. Тем не менее, я бы довольно уверенно писал правило перезаписи GHC, которое оптимизирует fmap id == id.Какие законы являются стандартными классами классов Haskell, которые должны поддерживаться?

Какие еще стандартные классы имеют неявные законы? (==) должно быть истинным отношением эквивалентности? Ord должны быть частичным заказа? Общий порядок? Можем ли мы хотя бы предположить, что это транзитивно? Анти-симметричны?

Эти последние несколько, кажется, не указаны в отчете Haskell 2010, и я не уверен, что буду писать правила перезаписи, используя их. Однако существуют ли какие-либо общие библиотеки? Как патологический пример может написать уверенно?

И, наконец, если предположить, что существует граница для того, насколько патологическим может быть такой экземпляр, существует ли стандартный всеобъемлющий ресурс для законов, которые должны поддерживаться каждым экземпляром класса типов?


В качестве примера, сколько проблем я был бы, чтобы определить

newtype Doh = Doh Bool 
instance Eq Doh where a == (Doh b) = b 

это просто трудно понять, или будет ли компилятор оптимизировать неправильно где-нибудь?

+4

Обратите внимание, что довольно много законов разумного звучания (включая те, которые неявно предполагаются существующим кодом), которые можно предложить для 'Ord',' Num' и связанных классов, будут нарушены экземплярами ' Float' и 'Double'. Например, использование NaN в качестве ключевых разрывов в «Data.Map» и проблемах точности означает, что сложение с плавающей запятой не является ассоциативным. –

+3

@ C.A.McCann, что просто означает, что прелюдия имеет примеры, которые она не должна! 'Float' и' Double' не должны быть членами 'Eq' –

+2

@PhilipJF: С одной стороны, я согласен. Но их экземпляр «Num» немного лучше, и после этой строки аргумента к его логическому завершению приводит к удалению каждого экземпляра, который сделает типы с плавающей точкой практически полезными. Кстати, [я продемонстрировал, как сломанный экземпляр «Ord» находится в старой записи.] (Http://stackoverflow.com/a/6399798/157360) –

ответ

5

Haskell report упоминает законы для:

  • функтора (например fmap id == id)
  • Монады (например m >>= return == m)
  • Integral (например (x ‘quot‘ y)*y + (x ‘rem‘ y) == x)
  • Num (abs x * signum x == x)
  • Show (showsPrec d x r ++ s == showsPrec d x (r ++ s))
  • Ix (например, , inRange (l,u) i == elem i (range (l,u)))

Это все, что я мог найти. В частности, в разделе, посвященном Eq (6.3.1), не упоминается никаких законов, а также не о следующем.

2

Мое собственное мнение о том, что законы «должны быть» не подтверждается всеми стандартными экземплярами, но я думаю, что

  • Eq должно быть отношение эквивалентности.
  • Ord должен быть общий порядок
  • Num должно быть кольцо, с fromInteger кольцевой гомоморфизм и abs/signum себя в очевидных способов.

Многозначный код будет принимать эти «законы», даже если они этого не делают. Это не проблема Haskell, ранний C разрешил компилятору переупорядочить арифметику в соответствии с алгебраическими законами, и большинство компиляторов имеют возможность повторно использовать такую ​​оптимизацию, даже если они не разрешены текущим стандартом и могут изменять результаты ваших программ.

+0

Я в основном согласен с вами , хотя, насколько мне известно, ничего плохого не происходит, если эти денотаты нарушаются. Это сердце того, что я хотел бы знать - как я ошибаюсь? Является ли определение нерефлексивного экземпляра «Eq» не просто «сложным», но и фактически оптимизированным, чтобы быть неправильным? –

+1

@tel Я сомневаюсь, что «оптимизирован, чтобы быть неправильным», но, безусловно, «заставляет многие функции иметь непредсказуемые результаты» –

+0

Да, на мой взгляд, есть «жесткий» сбой, когда правило перезаписи нарушает вас и «мягкий» сбой, когда вы идете против преобладающих предположений по всему языку, и это просто становится очень запутанным. Оба плохие, но хуже. Вероятно, квинтэссенциальным примером будет «Eq Double». –

 Смежные вопросы

  • Нет связанных вопросов^_^