gpt4 book ai didi

haskell - 具有关联类型同义词的 Data.Vector.Unbox 的自动派生

转载 作者:行者123 更新时间:2023-12-04 14:48:06 25 4
gpt4 key购买 nike

我有一个数据类型

newtype Zq q = Zq (IntType q)

其中 'q' 将是该类的一个实例
class Foo a where
type IntType a

而“IntType”只是与“q”相关的底层表示(即 Int、Integral 等)。

我想让 Zq 成为 Data.Vector.Unbox 的实例.我们目前正在使用上面链接中建议的大约 50 行简单代码手动派生 Unbox。我们将在我们的代码中制作几种不同类型的“拆箱”,因此为每种类型编写 50 行并不吸引人。

我找到了两种选择 here .一种替代方法是使用 this package它使用 Template Haskell 派生 Unbox 的实例。 TH 代码如下所示:
derivingUnbox "Zq"
[d| instance (Foo q, U.Unbox (IntType q)) => Unbox' (ZqBasic q) (IntType q) |]
[| \ (Zq x) -> x |]
[| \ x -> Zq x |]

问题是,我 can't define instances using associated type synonyms (或者我可以吗??)

[一个相关问题:为什么 TypeSynonymInstances ,FlexibleInstances 隐含的扩展,不允许 相关 类型同义词实例?这是某种根本不同的野兽吗?]

我目前对该问题的解决方案是将 Zq 重新定义为
newtype Zq q i = Zq i

然后添加等式约束
i~(IntType q)

在涉及 (Zq q i) 的每个实例中,这不是很优雅。我的(工作)拆箱派生变为
derivingUnbox "Zq"
[d| instance (U.Unbox i, i~IntType q, Foo q) => Unbox' (Zq q i) i |]
[| \ (Zq x) -> x |]
[| \ x -> Zq x |]

我觉得我应该能够在不诉诸于显式暴露类型“i”的情况下完成此操作。我所做的只是将它从关联的类型同义词移动到具有等式约束的显式参数。为什么这种“从根本上”是一种不同(而且显然更安全)的方法?有什么方法可以避免添加类型参数“i”并仍然获得自动拆箱派生?

除了额外的类型参数,我在使用 TH 包为 (Vector r) 派生 Unbox 时遇到了问题,也就是说,我想制作一个 Unbox Vector 的 Unbox Vector。我的尝试是这样的:
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 类型时。

第二种方法列出 above正在使用扩展 GeneralizedNewtypeDeriving。我看到这种方法的最大问题是我有一些需要拆箱的实际数据(而不是新类型)。但是,仅使用扩展名,我应该可以编写
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 时,这仍然(可能)不能解决我的问题。)

谢谢你的帮助!

最佳答案

我更改了 4820b73 中的语法,所以你现在应该可以做你想做的事了:

derivingUnbox "Complex"
[d| (Unbox a) ⇒ Complex a → (a, a) |]
[| \ (r :+ i) → (r, i) |]
[| \ (r, i) → r :+ i |]

我还修复了 fe37976 中的“xyz 不是(可见)方法……”错误。 ,尽管可以通过以下方式解决它:
import qualified Data.Vector.Generic
import qualified Data.Vector.Generic.Mutable

立即发布 Hackage .
抄送:@reinerp

关于haskell - 具有关联类型同义词的 Data.Vector.Unbox 的自动派生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11399143/

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