いうものを勉強してみた。日本語の資料は見事なまでに皆無だったので、(Haskellで、しかも試験的な機能だから止む無しか)英語の論文を読むことになった。10ページほど読むのに3日かかったけど...。...?大雑把に言うとコンパイル時にプログラムを生成するためのもののようである。概要コンパイル時に指定した式を実行させ、その値をコードの中に展開させることが出来る。展開できる式の値は"プログラム式"等の型をもつ。要するに、任意の方法で構文木を組み立てて、それを実行することが出来ると。大雑把なアイデア構文木はExpQという型を持つ。おいてはこのExpQ型の何かを扱えば良い。Expのシノニムであり、Expは単にHaskellのデータ型、QはQuotationモナドというように説明されている。Quotationモナドであるが、これはほぼIOモナドと同じだろう。実際のところQモナドとIOモナドは相互変換可能である。IOに加え、コンパイラの内部状態にアクセスするためにこのようになっていると思われる。構文木の構築においてExpQという型を持ち出すのは構築の際に任意のIOを行わせるためだろう。全容はLanguage.Haskell.THSyntaxに定義されている。これとモナド演算だけを用いてプログラムを構築することも出来るのだが、それはあまりにも冗長で煩雑であるので、利便性のためにもっと別な方法で記述できるようになっている。Haskellの記述方法には3つのやり方がある。それぞれ順番に記述力が下がり、利便性が上がる。最初は、先に書いたExp型等をそのまま扱う方法。次に、それのモナディック版を使う方法。VarEに対してvarE、AppEに対して、appEなど、先頭が小文字な関数バージョンが定義されており、これらはいずれもExpQ上の関数として定義されている。これらを用いることにより、明示的なモナド操作が減少する。最後に、quasi-quote記法というものを用いる方法。これはSchemeにあるquasi-quoteに大体で似ている。囲った部分の式をExpQな型として扱える。途中に$(式)と書くことにより、その中の式を実行したものを埋め込むことが出来る。|]適当な例として階乗を。quasi-quote記法では色々と記述しきれない部分があるのでこれら3つの手法を組み合わせて目的のコードを作成することになる。これらの手法はシームレスに混合可能である。作成したものをコンパイル時に実行させるには(unquoteと同様に)$を頭につければよい。10)3628800式として書かれるべき場所でトップレベルな展開が発生した場合、その計算したものの型がExpQであった場合、そこにコードが挿入されるような感じであろうか。定義を書くべき場所であれば、DecQ型を返せばそこに宣言を挿入することも出来る。printf普通なHaskellではprintfのような関数を定義しようと思っても型を付けることが出来ない。型は引数の文字列によって変わるからなのである。Haskellなら可能である。なる式にしてしまうことが出来るからである。|]まず、StringをFormatのリストに変換し、それをExpQに構築する。GHCではなぜかtop-levelなspliceはローカルな定義ではなくてimportしたものじゃないと駄目だといわれるので、Printfモジュールを作成している。123このように使用することが出来る。sprintfは左記の通り変換されるので、型チェックも問題なく行えるようだ。bのようなものを書かなければならない。'a'のような、自動的にそのような式を生成するものを記述することが出来る。[1..b]]上記、sel関数は、quasi-quoteだけでは書けない。...と、ここでb要素のタプルが書けないのである。上のように必要に応じてモナディックな関数で構成すれば定義できる。Haskellの格好の題材のようであるが、次はzipである。3)と書ければ嬉しいという話。scopingのためにzpという名前の扱いがややトリッキー(...でもないか)になっているが、まぁ、こんな感じで。なるパターンを生成したかった。上のような感じになってしまった。他にやり方がわからなかった。http://www.haskell.org/th/papers/meta-haskell.ps率直な感想...構文木を作るコード書くのめんどくさすぎ...自分で書こうと思っても全然書けない。慣れの問題なのだろうか...?http://www.haskell.org/ghc/docs/latest/html/libraries/haskell-src/Language.Haskell.THSyntax.htmlここにもほとんど説明が付いていないし、いろいろ大変だ。writeup月別アーカイブはてなブログをはじめよう!tanakhさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。