3

Template Haskell を学ぼうとしています。isLeft演習として、 andのようなものを生成できる関数を作成しました (この質問isRightに触発されました)。これが私の謙虚な試みです:

isA connam = do
    ConE nam <- connam
    nn <- newName "p"
    lamE [varP nn] $ caseE (varE nn) [
                       match (conP nam [wildP]) ( normalB [| True |] ) [],
                       match wildP ( normalB [| False |] ) [] 
                     ]

問題は、引数が 1 つのコンストラクターでのみ機能することです。犯人はconP nam [wildP]パターンです。理想的にconP nam (replicate (numArgs nam) wildP)numArgs、 はコンストラクタの引数の数を返す関数です。しかし、そのような関数をどのように書くのでしょうか? 関連するデータ宣言にアクセスする必要があると思いますが、その方法がわかりません。

これとまったく同じ機能について、別の質問がここにあります。

4

1 に答える 1

7

reifyデータ コンストラクターのアリティを決定するために型を使用して調べることもできますが、レコード パターンを使用してアリティに依存しないコードを生成する方がはるかに簡単です。

isFoo :: Bar -> Bool
isFoo p = case p of
    (Foo {}) -> True     -- Valid no matter what the arity of Foo is
    _        -> False

conPこれは、コード内でに置き換えることで実行できrecPます。

isA connam = do
    ConE nam <- connam
    nn <- newName "p"
    lamE [varP nn] $ caseE (varE nn) [
                       match (recP nam []) ( normalB [| True |] ) [],
                       match wildP ( normalB [| False |] ) [] 
                     ]
于 2011-08-27T12:06:37.743 に答える