Существует ли способ реализовать ограничения в классах типа Haskell?

Есть ли некоторый путь (какой-либо путь) для реализации ограничений в классах типа?

Как пример того, о чем я говорю, предположите, что я хочу реализовать Группу как класс типа. Таким образом, тип был бы группой, если существует три функции:

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, является единственной возможной группой с двумя элементами из-за ограничений). Существует ли способ сделать эту работу?

11
задан Rafael S. Calsaverini 29 January 2015 в 13:03
поделиться

3 ответа

Есть ли способ применить такого рода ограничения?

Нет . Многие людей просили об этом, в том числе прославленный Тони Хоар, но пока ничего не появляется на горизонте.

Эта проблема могла бы стать отличной темой для обсуждения группы Haskell Prime . Если кто-то выдвинул хорошее предложение, его, наверное, там и можно найти.

P.S. Это важная проблема!

11
ответ дан 3 December 2019 в 04:32
поделиться

Классы типов могут содержать как определения, так и объявления. Пример:

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, но не гарантируется, что компилятор будет их использовать. Типичный пример - монадические законы

5
ответ дан 3 December 2019 в 04:32
поделиться

В некоторых случаях вы можете указать свойства с помощью QuickCheck. Это не совсем принудительное исполнение, но оно позволяет предоставить общие тесты, которые должны пройти все экземпляры. Например, используя Eq, вы можете сказать:

prop_EqNeq x y = (x == y) == not (x != y)

Конечно, автор экземпляра должен вызвать этот тест.

Было бы интересно сделать это для законов монад.

8
ответ дан 3 December 2019 в 04:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: