我使用Rep A
函数修改某种类型forall x. Rep A x -> F (Rep A) x
,其中F
是一个类型系列。让我们说这包裹了Maybe
中的所有字段。我想要做的是将F (Rep A)
序列化为JSON。 aeson
提供了序列化泛型类型的函数,但它并没有提供对实际泛型表示进行操作的函数。
为了解决这个问题,我想我可以写这样的东西
newtype RepWrapper a = RepWrapper (F (Rep a))
使用通用实例
instance Generic a => Generic (RepWrapper a) where
type Rep (RepWrapper a) = F (Rep a)
然后我可以在这个包装的值上使用aeson
函数。
上述问题是需要提供给Rep
的额外类型参数。据我所知,有三种方法可以做到这一点
newtype RepWrapper a = RepWrapper (forall x. F (Rep a) x)
data RepWrapper a = forall x. RepWrapper (F (Rep a) x)
newtype RepWrapper a x = RepWrapper (F (Rep a) x)
第一种方式让我编写from
函数,第二种方式让我编写to
函数,第三种方式似乎没用。
有没有办法定义包装器,所以我可以实现整个Generic
实例?
答案 0 :(得分:1)
给定数据类型> humcon
seqnames start end TAS Proxy.start Proxy.end Assembly_NCBI
1 6 28179560 28294888 rs1635 rs78270345 rs4711167 GRCh38.p7
2 3 52833805 52847601 rs3617 rs3617 rs2071044 GRCh38.p7
3 15 91426560 91426560 rs4702 rs4702 rs4702 GRCh38.p7
4 19 45382034 45382034 rs6859 rs6859 rs6859 GRCh38.p7
,A
给出通用表示Generic
的同构。在这里,我们想要反过来。给定通用表示Rep A
(此处为r
r ~ F (Rep A)
),我们希望数据类型A
为B
。我们将Rep B ~ r
定义为B
:
Data r
data Data r = Data (r ())
的类型参数是幻像(实际上,它由r :: * -> *
使用,没有人使用Generic1
),所以我们可以用任何东西实例化它,然后选择{{1作为任意默认值。
我们需要将幻象表达为约束。一种方法是采用Generic1
和Contravariant
的结合。
()
我还在 generic-data 中定义了Data
,其中我保留了额外的参数而不是实例化它,因为它实际上很便宜。