gpt4 book ai didi

haskell - 我可以派生 `Data` 的新类型实例吗?

转载 作者:行者123 更新时间:2023-12-02 12:44:29 30 4
gpt4 key购买 nike

我有一个新类型T:

newtype T = T Text

我想为其导出数据。因此,使用 -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’

可能相关: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.

要点是: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 构造函数。

关于haskell - 我可以派生 `Data` 的新类型实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52496506/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com