我可以导出“Data”的新类型实例吗?
Can I derive a newtype instance of `Data`?
我有一个新类型T
:
newtype T = T Text
我想为它导出Data
。所以 -XGeneralizedNewtypeDeriving -XDerivingStrategies
我做
deriving newtype instance Data T
我希望这对 GHC 来说是一个简单的推导,但我收到了一条令人讨厌的错误消息(附在下面)。错误消息似乎来自 coerce
的应用程序 newtype
推导。
如果我对角色注解的理解是正确的,他们需要在 Data
的实例方法上进行类型声明,但还有 none。我需要推出自己的实例吗?
• 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 fails for PersistFieldSql
编辑:也许我应该使用 -XDeriveDataTypeable
?
来自docs:
A derived instance is derived only for declarations of these forms
(after expansion of any type synonyms):
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)
where [...]
- C is not
Read
, Show
, Typeable
, or Data
. These classes should not “look through” the type or its constructor. You can still derive these
classes for a newtype, but it happens in the usual way, not via this
new mechanism. Confer with Default deriving strategy.
重点是:newtype
的 Data
实例应该根据 newtype
本身的构造函数来制作,而不是根据底层的(几个)构造函数类型。
广义 newtype
实例只是 "coerce" 基础类型的 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 derived" 实例会在此处产生 A
,暴露底层构造函数而不是预期的 T
构造函数。
我有一个新类型T
:
newtype T = T Text
我想为它导出Data
。所以 -XGeneralizedNewtypeDeriving -XDerivingStrategies
我做
deriving newtype instance Data T
我希望这对 GHC 来说是一个简单的推导,但我收到了一条令人讨厌的错误消息(附在下面)。错误消息似乎来自 coerce
的应用程序 newtype
推导。
如果我对角色注解的理解是正确的,他们需要在 Data
的实例方法上进行类型声明,但还有 none。我需要推出自己的实例吗?
• 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 fails for PersistFieldSql
编辑:也许我应该使用 -XDeriveDataTypeable
?
来自docs:
A derived instance is derived only for declarations of these forms (after expansion of any type synonyms):
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)
where [...]
- C is not
Read
,Show
,Typeable
, orData
. These classes should not “look through” the type or its constructor. You can still derive these classes for a newtype, but it happens in the usual way, not via this new mechanism. Confer with Default deriving strategy.
重点是:newtype
的 Data
实例应该根据 newtype
本身的构造函数来制作,而不是根据底层的(几个)构造函数类型。
广义 newtype
实例只是 "coerce" 基础类型的 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 derived" 实例会在此处产生 A
,暴露底层构造函数而不是预期的 T
构造函数。