私はデータ型を持っています
newtype Zq q = Zq (IntType q)
ここで、「q」はクラスのインスタンスになります
class Foo a where
type IntType a
'IntType'は、'q'に関連付けられた基底表現(つまり、Int、Integralなど)です。
ZqをData.Vector.Unboxのインスタンスにしたい。上記のリンクで提案されているように、現在、約50行の簡単なコードを使用してUnboxを手動で導出しています。コードでいくつかの異なるタイプの「Unbox」を作成するため、タイプごとに50行を書き込むのは魅力的ではありません。
ここで2つの選択肢を見つけました。1つの代替手段は、テンプレートHaskellを使用してUnboxのインスタンスを派生させるこのパッケージを使用することです。THコードは次のようになります。
derivingUnbox "Zq"
[d| instance (Foo q, U.Unbox (IntType q)) => Unbox' (ZqBasic q) (IntType q) |]
[| \ (Zq x) -> x |]
[| \ x -> Zq x |]
問題は、関連付けられたタイプの同義語を使用してインスタンスを定義できないことです(またはできますか??)
[関連する質問:FlexibleInstancesによって暗示される拡張機能であるTypeSynonymInstancesが、関連付けられたタイプの同義語インスタンスを許可しないのはなぜですか?これはどういうわけか根本的に別の獣ですか?]
その問題に対する私の現在の解決策は、Zqを次のように再定義することです。
newtype Zq q i = Zq i
次に、等式制約を追加します
i~(IntType q)
(Zq qi)を含むすべてのインスタンスで、これはあまりエレガントではありません。私の(作業中の)Unboxの派生は
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」の追加を回避し、それでも自動Unbox派生を取得できる方法はありますか?
追加の型パラメーターは別として、THパッケージを使用して(Vector r)のUnboxを導出するのに問題があります。つまり、UnboxVectorのUnboxVectorを作成したいと思います。私の試みは次のようなものです。
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タイプで問題なく機能するのに、なぜこのメソッドが見つからないのかわかりません。
上記の2番目のアプローチは、拡張機能GeneralizedNewtypeDerivingを使用することです。このアプローチで私が目にする最大の問題は、Unboxにする必要のある実際のデータ(Newtypeではなく)があることです。ただし、拡張機能を使用するだけで、次のように記述できるはずです。
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)) ""
そして2番目は与える:
No instance for (M.MVector MVector i) ""
No instance for (G.Vector U.Vector i) ""
上記の投稿から、派生できるはずだと私は信じているので、なぜこれらのインスタンスを派生できないのかわかりません。おそらく、GeneralizedNewtypeDerivingで関連付けられた型の同義語を使用することで逃げることができますか?(これでも(おそらく)データのUnboxを導出する必要がある場合、問題は解決しません。)
ご協力いただきありがとうございます!