我可以派生"数据"的新型实例吗?



我有一个新的类型T

newtype T = T Text

我想为它推导出Data。所以有了-XGeneralizedNewtypeDeriving -XDerivingStrategies我做的

deriving newtype instance Data T

我希望这是 GHC 的一个不费吹灰之力的推导,但我收到一条令人讨厌的错误消息(附在下面(。错误消息似乎来自newtype派生所产生的coerce的应用。

如果我正确理解角色注释,它们需要在实例方法上进行类型声明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’

可能相关:PersistFieldSql 的 GeneralizedNewtypeDeriving 失败

编辑:也许我应该只使用-XDeriveDataTypeable

从文档中:

派生

实例仅针对这些形式的声明派生 (扩展任何类型的同义词后(:

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 不是ReadShowTypeableData。这些类不应"查看"类型或其构造函数。您仍然可以推导出这些 新类型的类,但它以通常的方式发生,而不是通过这个 新机制。授予默认派生策略。

关键是:newtypeData实例应根据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

相反,"newtype 派生"实例将在此处产生A,公开基础构造函数而不是预期的T构造函数。

相关内容

  • 没有找到相关文章

最新更新