Ваше первоначальное определение гласило, что CouldBe m
был экземпляром Eq
для любого типа m
, даже того, который не имеет Eq
экземпляра.Но если это правда, вы должны найти какой-то способ определения Is x == Is y
без использования x == y
(поскольку вам не нужно m
, чтобы иметь экземпляр Eq
, x == y
не обязательно определен.)
В качестве конкретного примера, он запрещает вам писать что-то вроде
Is (+3) == Is (* 5) -- (+3) == (*5) is undefined
Добавление ограничения гарантирует, что вы можете сравнивать два значения CouldBe
только в том случае, если также можно сравнивать упакованный тип.
«Допустимый», но тривиальный экземпляр без добавления ограничения:
instance Eq (CouldBe m) where
Is x == Is y = True
Lost == Lost = True
_ == _ = False
Два значения CouldBe m
равны, если они совместно используют один и тот же конструктор данных, независимо отЗавершенное значение.Не делается никаких попыток использовать x
или y
, поэтому их типы могут быть неограниченными.
«Действительный» в кавычках, поскольку это определение может нарушать закон замещения, определенный в http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Eq.html. Предположим, у вас есть функция, которая может разделить значение CouldBe
:
couldbe :: b -> (a -> b) -> CouldBe a -> b
couldBe x _ Lost = x
couldBe _ f (Is x) = f x
Нарушение происходит потому, что Is 3 == Is 5
будет истиной, но пусть f = couldbe 0 id
.Затем f (Is 3) == f (Is 5)
оценивается как 3 == 5
, что ложно.
Является ли это на самом деле нарушением или нет, зависит от существования функции, подобной couldbe
, которая может видеть "внутри" aCouldBe
значение.