11

リングZ/nを作成しようとしています(通常の算術のようですが、整数を法として)。インスタンスの例はZ4です。

instance Additive.C Z4 where
  zero = Z4 0
  (Z4 x) + (Z4 y) = Z4 $ (x + y) `mod` 4

リングについても同様です。私はこれらのものを素早く生成できるようにしたいと思っています、そしてそれを行う方法はテンプレートhaskellを使うことだと思います。理想的には、上記で定義したように$(makeZ 4)、コードを吐き出してもらいたいと思います。Z4

しかし、私はこれに多くの問題を抱えています。するとgenData n = [d| data $n = $n Integer]、「データ/ニュータイプ宣言の解析エラー」が発生します。ただし、変数を使用しない場合は機能し[d| data Z5 = Z5 Integer |]ます。これは、変数で何か奇妙なことをしていることを意味しているに違いありません。でもわかりません。newNameを介してそれらを構築しようとしましたが、それも機能しなかったようです。

誰かがここで何が起こっているのか私を助けることができますか?

4

1 に答える 1

13

テンプレートHaskellのドキュメントには、スプライスできるものがリストされています。

の代わりにスプライスが発生する可能性があります

  • 表現; スプライスされた式はタイプでなければなりませんQ Exp
  • タイプ; スプライスされた式はタイプでなければなりませんQ Typ
  • トップレベルの宣言のリスト。スプライスされた式はタイプでなければなりませんQ [Dec]

ただし、どちらの場合も、名前$nをつなぎ合わせようとしています。

これは、引用符とスプライスを使用してこれを行うことができないことを意味します。モジュールで使用可能なさまざまなコンビネータを使用して宣言を作成する必要がありLanguage.Haskell.THます。

これはあなたがやろうとしていることと同等であるべきだと思います。

genData :: Name -> Q [Dec]
genData n = fmap (:[]) $ dataD (cxt []) n []
                           [normalC n [strictType notStrict [t| Integer |]]] []

うん、それは少し醜いですが、そこに行きます。これを使用するには、新しい名前で呼び出します。例:

$(genData (mkName "Z5"))
于 2011-09-27T01:35:41.157 に答える