我有一个数据类型
newtype Zq q = Zq (IntType q)
其中,“Q”将是类的一个实例
class Foo a where
type IntType a
和“IntType上”只是用“Q”相关联的基本表示(即中等,积分等)。
我想使ZQ的实例Data.Vector.Unbox 。 我们目前正在使用手动约50的琐碎代码行导出的Unbox如在链接建议的上方。 我们将在代码中做几种不同类型“的Unbox”,所以写50行每类是没有吸引力。
我发现了两个备选方案在这里 。 一个替代方案是使用这个包 ,它使用模板的Haskell导出的Unbox的实例。 该TH代码是这样:
derivingUnbox "Zq"
[d| instance (Foo q, U.Unbox (IntType q)) => Unbox' (ZqBasic q) (IntType q) |]
[| \ (Zq x) -> x |]
[| \ x -> Zq x |]
问题是,我使用相关联的类型的同义词不能定义实例 (或I可以??)
[一个相关的问题:为什么TypeSynonymInstances ,延伸通过FlexibleInstances暗示,不容许相关类型同义词实例? 这是莫名其妙本质上是一个不同的野兽?]
我目前的解决这一问题是重新定义为ZQ
newtype Zq q i = Zq i
然后添加等式约束
i~(IntType q)
在涉及(ZQ气),这是不是很优雅的每个实例。 我的(工作)的Unbox推导变
derivingUnbox "Zq"
[d| instance (U.Unbox i, i~IntType q, Foo q) => Unbox' (Zq q i) i |]
[| \ (Zq x) -> x |]
[| \ x -> Zq x |]
我觉得我应该能够做到这一点,而不诉诸明确地暴露型“我”。 所有我所做的是从相关类型代名词移动它与等式约束明显的参数。 为什么这是“根本”不同的(显然更安全)的方法呢? 有一些方法可以让我避免增加类型参数“我”,仍然可以得到自动拆箱推导?
额外的类型参数不谈,我在使用的TH包导出的Unbox为(矢量R)的麻烦,那就是我想要的Unbox向量的向量的Unbox。 我的尝试是这样的:
newtype Bar r = Bar (Vector r)
derivingUnbox "Bar"
[d| instance (Unbox r) => Unbox' (Bar r) (Vector r) |]
[| \ (Bar x) -> x |]
[| \ x -> Bar x |]
但我得到的(大量的),如错误:
`basicUnsafeFreeze` is not a (visible) method of class `Data.Vector.Generic.Base.Vector`
我不知道为什么它不能找到这个方法,当它工作得很好,我ZQ型。
列出的第二个方法以上被使用扩展GeneralizedNewtypeDeriving。 我用这种方法看到的最大的问题是,我有一些实际的数据(而不是NEWTYPE)是我需要的Unbox。 然而,仅仅使用扩展,我应该能够编写
newtype Zq q = Zq (IntType q) deriving (Unbox, M.MVector MVector, G.Vector Vector)
或至少
newtype Zq q i = Zq i deriving (Unbox, M.MVector MVector, G.Vector Vector)
首先导致的错误:
No instance for (Unbox (IntType q)) arising from the `deriving` clause of a data type declaration
No instance for (M.MVector MVector (IntType q)) ""
No instance for (G.Vector Vector (IntType q)) ""
而第二得出:
No instance for (M.MVector MVector i) ""
No instance for (G.Vector U.Vector i) ""
我不知道为什么它不能得出这些情况下,如上面的帖子使我相信它应该可以。 也许我可以摆脱使用与GeneralizedNewtypeDeriving关联的类型代名词? (这仍然(可能),当我需要得到的Unbox为“数据的不解决我的问题。)
谢谢你的帮助!