Могу ли я получить экземпляр нового типа `Data`? - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть новый тип T:

newtype T = T Text

Я хочу получить Data для него.Так что с -XGeneralizedNewtypeDeriving -XDerivingStrategies я делаю

deriving newtype instance Data T

Я ожидаю, что это будет легким выводом для GHC, но я получаю неприятное сообщение об ошибке (прилагается ниже).Похоже, что сообщение об ошибке исходит от применения coerce, вызванного производным newtype.

Если я правильно понимаю аннотации ролей, им нужно будет перейти к объявлению типа в методах экземпляра для Data пока их нет.Нужно ли мне катить свой собственный экземпляр?

    • Couldn't match representation of type ‘c1 Text’
                               with that of ‘c1 T’
        arising from a use of ‘ghc-prim-0.5.2.0:GHC.Prim.coerce’
      NB: We cannot know what roles the parameters to ‘c1’ have;
        we must assume that the role is nominal
    • In the expression:
        ghc-prim-0.5.2.0:GHC.Prim.coerce
          @(forall (c :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep
                         -> TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
            forall (d :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep)
                   (b :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
            Data d => c (d -> b) -> d -> c b
            -> forall (g :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
               g -> c g
               -> Text -> c Text)
          @(forall (c :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep
                         -> TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
            forall (d :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep)
                   (b :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
            Data d => c (d -> b) -> d -> c b
            -> forall (g :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
               g -> c g
               -> T -> c T)
          gfoldl
      In an equation for ‘gfoldl’:
          gfoldl
            = ghc-prim-0.5.2.0:GHC.Prim.coerce
                @(forall (c :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep
                               -> TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
                  forall (d :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep)
                         (b :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
                  Data d => c (d -> b) -> d -> c b
                  -> forall (g :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
                     g -> c g
                     -> Text -> c Text)
                @(forall (c :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep
                               -> TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
                  forall (d :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep)
                         (b :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
                  Data d => c (d -> b) -> d -> c b
                  -> forall (g :: TYPE ghc-prim-0.5.2.0:GHC.Types.LiftedRep).
                     g -> c g
                     -> T -> c T)
                gfoldl
      When typechecking the code for ‘gfoldl’
        in a derived instance for ‘Data T’:
        To see the code I am typechecking, use -ddump-deriv
      In the instance declaration for ‘Data T’

Возможно, связано: Сбой GeneralizedNewtypeDeriving для PersistFieldSql

РЕДАКТИРОВАТЬ: Возможно, я должен просто использовать -XDeriveDataTypeable?

1 Ответ

0 голосов
/ 25 сентября 2018

Из документов :

Производный экземпляр выводится только для объявлений этих форм (после раскрытия синонимов любого типа):

newtype T v1..vn                   = MkT (t vk+1..vn) deriving (C t1..tj)
newtype instance T s1..sk vk+1..vn = MkT (t vk+1..vn) deriving (C t1..tj)

где [...]

  • C не Read, Show, Typeable или Data.Эти классы не должны «просматривать» тип или его конструктор.Вы все еще можете получить эти классы для нового типа, но это происходит обычным способом, а не с помощью этого нового механизма.Согласитесь с Стратегия получения по умолчанию .

Дело в том, что Data экземпляр для newtype должен быть создан в соответствии с конструктором newtypeсам по себе, а не к (нескольким) конструкторам базового типа.

Обобщенный экземпляр newtype просто "приведет" экземпляр Data базового типа к newtype, но это будетбыть неправым.

(Полученное вами сообщение об ошибке могло бы быть более полезным.)

Заключение: попробуйте вместо этого использовать DeriveDataTypeable.Это должно привести к правильному экземпляру.

newtype T = T Text deriving (Data)

Точнее, мы должны увидеть это в надлежащем экземпляре:

> data U = A | B deriving Data
> newtype T = T U deriving Data
> toConstr (T A)
T

Вместо этого экземпляр "производного от нового типа" дастA здесь, обнажая нижележащий конструктор вместо намеченного T one.

...