Есть ли словарь для [классов типов без методов]?Что он содержит?
Да, есть словарь без полей.
Сравнить:
class Monoid a where
mempty :: a
mappend :: a -> a -> a
data DictMonoid a = DictMonoid a (a -> a -> a)
class C a
data DictC a = DictC
Если M
импортируетсяв какой-то другой модуль (с C
экземплярами), как закодирован поиск по словарю f
?
Вывод типа используется для определения, какой экземпляр необходим при вызове f
;затем GHC ищет этот тип в своей коллекции известных экземпляров (= известных словарей).
Одним из возможных результатов этого процесса является то, что экземпляр, который мы определили как необходимый, является полиморфным, и полностью полиморфного экземпляра не существует.Затем соответствующее ограничение (например, C a
или C m
или что-либо еще) присоединяется к предполагаемому типу любого термина, вызывающего f
, который затем компилируется в функцию, которая принимает словарь для f
.имени и передает его.
Для классов типов без методов с ограничениями суперкласса: Куда идут ограничения в словаре?
Где-то.Там нет никакого наблюдения вы можете сделать с поверхности языка, чтобы различать разные места.Например, рассмотрим:
class Semigroup a => Monoid a where mempty :: a
data DictMonoid1 a = DictMonoid1 (DictSemigroup a) a
data DictMonoid2 a = DictMonoid2 a (DictSemigroup a)
Это всего лишь два варианта выбора словаря суперкласса.Но какое это может иметь значение?
Хорошо, но вы спросили о классах типов без методов.Но ответ тот же.Вы не можете определить порядок хранения словарей суперкласса.
class (A a, B a) => C a
data DictC1 a = DictC1 (DictA a) (DictB a)
data DictC2 a = DictC2 (DictB a) (DictA a)
Что вы могли бы сделать, чтобы определить разницу между ними?Ничего.
Для экземпляров классов типов без методов с ограничениями: Опять же, куда идут ограничения в словаре?
Нигде.Они становятся аргументами, которые вызывающая сторона должна предоставить для получения словаря.Конкретные поля поставляемого словаря могут быть закрыты новым словарем, конечно.Пример:
class Ord a where compare :: a -> a -> Ordering
data DictOrd a where DictOrd (a -> a -> Ordering)
instance (Ord a, Ord b) => Ord (a, b) where
compare (a,b) (a',b') = compare a a' <> compare b b'
instanceOrdTuple :: DictOrd a -> DictOrd b -> DictOrd (a,b)
instanceOrdTuple (DictOrd comparea) (DictOrd compareb)
= DictOrd $ \(a,b) (a',b') -> comparea a a' <> compareb b b'
Хорошо, но вы спросили о классах типов без методов.Но ответ существенно не отличается.Словари ограничений экземпляра нигде не хранятся, как прежде;единственное отличие состоит в том, что теперь мы также можем быть уверены, что даже поля поставляемых словарей не закрыты.
class A a where whateverA :: a -> Int
class B a where whateverB :: Int -> a
class C a
data DictA a = DictA (a -> Int)
data DictB a = DictB (Int -> a)
data DictC a = DictC
instance (A a, B a) => C [a]
instanceCList :: DictA a -> DictB a -> DictC [a]
instanceCList (DictA whateverAa) (DictB whateverBa) = DictC
Следующий комментарий отвечает на старую версию вопроса.
В этом модуле нет экземпляров для C
, поэтому компилятор не может выполнить ограничение f
s.
В этом нет необходимости.f
компилируется в функцию, которая принимает словарь в качестве аргумента;нет необходимости создавать словарь для компиляции f
, только для компиляции его вызывающих.
Компилятор не может выполнить ограничение C Char
, возникающее из уравнения для y
.Что он делает?
Он сообщает, что не может выполнить ограничение C Char
и завершается неудачно.(Это вряд ли можно квалифицировать как вопрос - просто попробуйте и убедитесь сами!)