я думал, что exist-квантификация это вот такой кейс, где a неявно (в core явно) превращается в пару из значения и инстанса
окей, я просмотрел core и пришел к такому выводу:
data T = ToString (forall a. Show a => a)
не работает по такой же причине, почему не работает и
f :: (forall a. Show a => a) -> String
exist значение это по сути пара (в нашем случае тройка из типа, инстанса и значения), а ghc не может тупо взять значение и превратить его в кортеж и потом везде разворачивать/заворачивать. В первом случае у нас такое значение как аргумент конструктора, во втором как аргумент функции.
а вот когда мы уже на уровне всего конструктора все это делаем, то ghc нефиг делать добавить в конструктор пару дополнительных скрытых полей: и тип, и инстанс, поэтому
data T = forall a. Show a => ToString a
прекрасно работает и на самом деле консруктор ToString содержит 3 значения:
ToString @(a :: Type) ($show :: Show a) (x :: a)
то есть ghc не хочет создавать exist-кортежи из значений, а вот расширять другие кортежи до exist спокойно, то есть это все просто проблема реализации