Есть ли некоторый путь (какой-либо путь) для реализации ограничений в классах типа?
Как пример того, о чем я говорю, предположите, что я хочу реализовать Группу как класс типа. Таким образом, тип был бы группой, если существует три функции:
class Group a where
product :: a -> a -> a
inverse :: a -> a
identity :: a
Но это не функции, но они должны быть связаны некоторыми ограничениями. Например:
product a identity = a
product a (inverse a) = identity
inverse identity = identity
и т.д...
Существует ли способ осуществить этот вид ограничения в определении класса так, чтобы какой-либо экземпляр автоматически наследовал бы его? Как пример, предположите, что я хотел бы реализовать группу C2, определенную:
data C2 = E | C
instance Group C2 where
identity = E
inverse C = C
Это два определения исключительно определяют C2 (ограничения выше определяют все возможные операции - на самом деле, C2, является единственной возможной группой с двумя элементами из-за ограничений). Существует ли способ сделать эту работу?
Есть ли способ применить такого рода ограничения?
Нет . Многие людей просили об этом, в том числе прославленный Тони Хоар, но пока ничего не появляется на горизонте.
Эта проблема могла бы стать отличной темой для обсуждения группы Haskell Prime . Если кто-то выдвинул хорошее предложение, его, наверное, там и можно найти.
P.S. Это важная проблема!
Классы типов могут содержать как определения, так и объявления. Пример:
class Equality a where
(?=), (!=) :: a -> a -> Bool
a ?= b = not (a != b)
a != b = not (a ?= b)
instance Eq a => Equality a where
(?=) = (==)
test = (1 != 2)
Вы также можете указать специальные ограничения (назовем их законами ) в простом Haskell, но не гарантируется, что компилятор будет их использовать. Типичный пример - монадические законы
В некоторых случаях вы можете указать свойства с помощью QuickCheck. Это не совсем принудительное исполнение, но оно позволяет предоставить общие тесты, которые должны пройти все экземпляры. Например, используя Eq, вы можете сказать:
prop_EqNeq x y = (x == y) == not (x != y)
Конечно, автор экземпляра должен вызвать этот тест.
Было бы интересно сделать это для законов монад.