5

モナド内包表記を使用して SQL クエリを表し、適切な SQL を生成することを検討しています。一見すると、これは問題ではなく、ぴったりと合っているように見えます。しかし、モナドを積だけで形成できる型を制限する必要があり、合計はありません。そのような制約を設定する方法は考えられません。

型チェッカーを使用して、SQL で表現可能な型のみを使用できるようにしたいと考えています。

テンプレート haskell を使用して正しいインスタンスを導出し、型が適合しない場合は導出を拒否することもできると思いますが、型レベルで行うことをお勧めします。無知なため、バグを導入する可能性が低くなります。

どうすればこれを行うことができますか? はいの場合、いくつかの読書やコード例をお勧めできますか。

編集:ありがとう、私は従うべきいくつかの良い道筋を持っています.

4

1 に答える 1

8

残念ながら、これは実際には不可能です。a はMonad完全にポリモーフィックでなければなりません。Setモナド (Ord制約)を作成できないのと同じ理由です。

結果の型が制約を満たすことだけに対処できる場合はrunSQL :: (Product a) => SQL a -> IO a、 、または同様のものを持つことができます。その場合、適切なインスタンスを Template Haskell で導出するか、代わりに新しいGHC Genericsを使用する方法です。単純な Haskell には、型が積だけで構成されているかどうかを判断する方法がありません。

しかし、モナド計算を SQL に変換するには、モナド計算の構造全体にアクセスする必要があると思います。残念ながら、モナドは「内部を見る」ことができない任意の Haskell 関数と一緒にプラグインされているため、これにはあまり適していません。矢印は近くにあり、より多くの静的分析を行うことができますが、それでもarr任意の Haskell 関数に忍び込むことができる厄介な点があります。

このようなことを行うための最も実行可能なオプションは、おそらくテンプレート Haskell スプライサーを作成して、必要な構文を解析することです。コンパイル時に AST を対応する SQL に変換することができます。その構文があまりにも醜い場合は、haskell-src-meta で quasiquoter を使用すると、次$(sql [| [ (a,b) | a <- table1, b <- table2 |])のようなります。sql[sql| (a, b) | a <- table1, b <- table2 |]

一般化された矢印拡張にも興味があるかもしれませんが、それはおそらくあなたの目的にはやり過ぎです (そしてあまりにも実験的です)。

于 2012-04-05T15:36:57.780 に答える