Haskell - двунаправленное значение типа экземпляра класса ИЛИ GADT квалификации экзистенциального типа? - PullRequest
2 голосов
/ 01 мая 2011

У меня есть GADT, определенный (сокращенно),

{-# LANGUAGE StandaloneDeriving #-}
data D t where
    C :: t -> D t
    R :: D b -> D (Either a b)
deriving instance Show t => Show (D t)

Компилятор правильно жалуется, что не может получить Show для R. В этом случае у нас есть (Either ab) класса Show,но мы не можем знать, что это правда, если b принадлежит к классу Show.Сообщение об ошибке:

Could not deduce (Show b) from the context (t ~ Either a b)
  arising from a use of `showsPrec' at tmp.hs:37:0-37
Possible fix: add (Show b) to the context of the constructor `R'
In the second argument of `(.)', namely `(showsPrec 11 b1)'
In the second argument of `showParen', namely
    `((.) (showString "R ") (showsPrec 11 b1))'
In the expression:
    showParen ((a >= 11)) ((.) (showString "R ") (showsPrec 11 b1))
When typechecking a standalone-derived method for `Show (D t)':
  showsPrec a (C b1)
              = showParen ((a >= 11)) ((.) (showString "C ") (showsPrec 11 b1))
  showsPrec a (R b1)
              = showParen ((a >= 11)) ((.) (showString "R ") (showsPrec 11 b1))

Кажется, что нужно иметь возможность квалифицироваться по экзистенциальному типу, говоря что-то вроде "Show b => Show (D (Either ab))" для экзистенциальных типов b.или обновите значение "(Показать a, Показать b) => Показать (либо ab)", чтобы оно было двунаправленным.

Большое спасибо!

(Пожалуйста, не стесняйтесь очищатьназвание или описание.)

1 Ответ

4 голосов
/ 01 мая 2011

Добавьте ограничение Show к экзистенциальному,

data D t where
    C :: t -> D t
    R :: Show b => D b -> D (Either a b)

, и вы в бизнесе.

Prelude> :r
[1 of 1] Compiling A                ( A.hs, interpreted )
Ok, modules loaded: A.
*A> R (C 7)
R (C 7)
...