У меня есть класс C
с экземплярами для одного типа и для кортежей.
class C a
instance C Int
instance (C a, C b) => C (a, b)
Использование обычного Dict
GADT для фиксации ограничений
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ConstraintKinds #-}
data Dict c where
Dict :: c => Dict c
можно ли доказать C a
от C (a, b)
?
fstDict :: Dict (C (a, b)) -> Dict (C a)
fstDict Dict = ???
Я подозреваю, что немедленный ответ будет «нет», поскольку fstDict Dict = Dict
недостаточно, и есть несколько других возможностей. Есть ли способ изменить C
, чтобы ограничения для компонентов продуктов можно было восстановить из ограничений на продукт?
Я, возможно, неправильно, пытаюсь выполнить то же самое, что и наиболее близкий вопрос, однако я могу позволить себе роскошь потребовать Dict
с одного или обоих концов категории.
data DSL a b where
DSL :: (Dict C a -> DSL' a b) -> DSL a b
data DSL' a b where
DSL' :: (C a, C b) => ... -> DSL' a b