7

私はデータ型を持っています

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を導出する必要がある場合、問題は解決しません。)

ご協力いただきありがとうございます!

4

2 に答える 2

4

4820b73の構文を変更したので、今すぐやりたいことができるはずです。

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

fe37976の「xyz is not a (visible) method…」エラーも修正しましたが、次の方法で回避できました。

import qualified Data.Vector.Generic
import qualified Data.Vector.Generic.Mutable

Hackageで公開中。CC: @reinerp

于 2012-11-18T06:35:38.567 に答える
3

ここでいくつかの問題が発生しています。

THアプローチ

はい、関連付けられた型シノニムのクラス インスタンスは不正です

関連する型シノニムまたは型関数のクラス インスタンスを定義できないのは事実です。これには正当な理由があります。コンパイラはそれらが重複しているかどうかを判断できません。例えば:

type family F a
instance Eq (F Int)
instance Eq (F Bool)

これらのインスタンスは重複していますか? 上記のソース コードを考えると、わかりません。誰かが後で のインスタンスをどのように定義するかによって異なりますF。たとえば、彼らは定義することができます

type instance F Int = Double
type instance F Bool = Double

の 2 つのインスタンスはEq実際には重複しています。

vector-th-unboxパッケージで問題が発生しています

必要な実際のインスタンスを見ると、実際には のUnboxインスタンスは必要ありませんIntType q。あなたが望むのはこれだけです:

instance (Unbox (IntType q), Foo q) => Unbox (Zq q) where
    ...

問題は、テンプレート Haskell の構文を悪用して型を渡す便利な方法として、vector-th-unboxパッケージが偽の型クラスを使用Unbox'して中間表現型 (あなたの場合) を伝達することを強制することです。IntType qそしてGHCはあなたが書いたことを見てUnbox' (Zq q) (IntType q)文句を言います。vector-th-unboxパッケージのバグを報告することをお勧めします。

Unbox為にVector r

ルイス・ワッサーマンがこれをカバーしたと思います。

GeneralizedNewtypeDerivingアプローチ_

特定のコンパイル エラーは、GHC が適切なコンテキストを推測できないためです。あなたが抱えている問題に似たほとんどの問題について、StandaloneDeriving言語拡張はあなたの問題を解決します:

deriving instance Unbox (IntType q) => Unbox (Zq q)
deriving instance Unbox (IntType q) => M.MVector MVector (Zq q)
deriving instance Unbox (IntType q) => G.Vector Vector (Zq q)

しかし、これをしないでください!

GeneralizedNewtypeDeriving多くの場合、まさにあなたが望むことを行いますが、いくつかの根本的な方法で壊れており、それUnbox生成するインスタンスは完全に壊れています! したがって、Liyang に現在の問題の修正を求めてロビー活動を行った後は、TH アプローチに固執してください。

于 2012-07-10T22:10:44.007 に答える