Это выглядит странно. У меня есть только частичный ответ, но я все равно отправлю его. Я упростил ваш код до
class C t where -- (*)
data T t where
T :: C t => (a -> t) -> a -> T t
foo ::
( C u
, forall a b . (C a , C b) => C (a, b) )
=> u -> T t -> T (u, t)
foo i (T f x) = T (\(a,b) -> (a, f b)) (i, x)
, и в этой версии он компилируется нормально. Однако, если мы заменим
class C t where
на
type instance C :: * -> Constraint
, мы получим ошибку, сообщающую нам, что C (a, b)
не может быть выведено.
Я не могу полностью понять, что здесь происходит, но похоже, что количественно определенные ограничения плохо сочетаются с семействами типов.
Похоже, что указанное выше семейство типов рассматривается как
type instance C (t :: *) :: Constraint
и в такой случай, я не могу понять в чем дело. Поскольку C
теперь не относится к классу одного типа, невозможно реализовать количественное ограничение, такое как forall a b . (C a , C b) => C (a, b)
, (скажем) передав указатель на конкретный экземпляр c, поскольку три ограничения C
могут быть что угодно, в открытом мире.
Я до сих пор не понимаю, почему type family C :: * -> Constraint
обрабатывается таким же образом.
Возможно, GH C должен отвергать количественные ограничения, связанные с семействами типов ... -> Constraint
таким образом? Я не уверен.