-
UndecidableSuperClasses -
- Начиная с:
-
8.0.1
Разрешить любые ограничения на суперклассы, включая те, которые могут привести к незавершению работы проверяющей типы системы.
Расширение языка UndecidableSuperClasses позволяет задавать гораздо более гибкие ограничения на суперклассы.
Класс, как правило, не может быть собственным суперклассом. Поэтому следующий код недопустим
class C a => D a where ... class D a => C a where ...
GHC консервативно выполняет эту проверку, если задействованы типовые функции или переменные типа. Например:
type family F a :: Constraint class F a => C a where ...
GHC выдаст ошибку, поскольку позднее вы можете добавить
type instance F Int = C Int
и тогда мы получим цикл суперклассов. Вот пример с переменной типа:
class f (C f) => C f class c => Id c
Если раскрыть суперклассы C Id, мы сначала получим Id (C Id), а затем снова C Id.
Но такие ограничения на суперклассы иногда полезны, а консервативная проверка раздражает, если фактической рекурсии нет.
Кроме того, действительно рекурсивные суперклассы иногда бывают полезны. Вот пример из реальной практики (#10318)
class (Frac (Frac a) ~ Frac a,
Fractional (Frac a),
IntegralDomain (Frac a))
=> IntegralDomain a where
type Frac a :: Type
В этом случае цикл суперклассов завершается, но заметить это не так-то просто.
С расширением языка UndecidableSuperClasses GHC снимает все ограничения на ограничения суперклассов. Если цикл действительно есть, GHC будет раскрывать его только до конечной глубины.