1

ユーザーが入力した文字列をHaskellソースコードとして動的にロードするプログラムの一部として、ユーザーの入力をコンパイルする前に前処理を行いたいと思います。

私ができるようにしたいことの1つは、特定の関数オカレンスのソースを検索し、それらに追加の引数を追加することです。したがって、たとえば、次のすべてのオカレンスが必要になる場合があります。

addThreeNumbers 3 5

になるために:

addThreeNumbers 3 5 10

そのような行動を達成するための最良の方法は何ですか?GHC API / Template Haskellの関数を使用して、ある種の抽象構文ツリーを操作することを保証するのに十分複雑ですか?それとも、これはある種のHaskell前処理/解析ライブラリで実現できる単純なものですか?もしそうなら、どのライブラリとリソースをお勧めしますか?

4

1 に答える 1

1

Ghc 7.6修飾インポート、ghc-pkg hidden、およびghcの-packageオプションを使用すると、インポートファイルとインポートファイルの間にレイヤーをシームレスに追加できます。

例:

標準の.cabalファイルとcabalインストールを使用して、独自のData.Charを使用してパッケージを作成します。

{-# language PackageImports #-}                                                  

module Data.Char (                                                               
      toUpper                                                                    
    , Char                                                                       

    , String                                                                     
    -- ...  Export every else from "Base" Data char because the limitation of
    --     the current export facility you can not use
    --     module Data.Char hiding (toUpper)
    ) where                                                                      

import "base" Data.Char hiding (toUpper)                                         
import qualified "base" Data.Char as OldChar                                     

toUpper :: Char -> IO Char                                                       
toUpper c = do                                                                   
    print "Oh Yeahhhhhhhhh"                                                      
    return $ OldChar.toUpper c

基本パッケージghc-pkg hide baseを非表示にします。これにより、多くのモジュールが非表示になります。この場合、必要に応じてすべてのモジュールをラップする必要があります。

> ghci -XNoImplicitPrelude --  We need language flag because the Prelude is in
                           -- base and I did not make a wrapped Prelude
ghci> import Data.Char
ghci> toUpper 'c'  -- The wrapped function
"Oh Yeahhhhhhhhh"
'C'
ghci> isSpace ' '  -- The unwrapped normal Data.Char function
True

これで、テンプレートHaskellを使用して関数をラップし、外部情報を取得するために必要なIOアクションを呼び出すことができます。ユーザーは、名前に「internal」を追加するバリエーションを使用して、関数呼び出しやモジュールのインポートを変更する必要もありません。

モジュールインターフェイスをシームレスにラップできるということは、パッケージ/モジュールコードまたは使用している既存のコードベースに触れることなく、インポートされたモジュールの埋め込みを変更できることも意味します。中間層を作成するだけです。

質問への回答を編集します。

確かに、ghc-apiを使用するとすべてを実行できますが、かなり複雑で、私が望むよりも少ない例が浮かんでいて、サクセスストーリーよりも苦労している人が増えているようです。

  • コードヒントの評価用
  • モジュールの動的負荷にはプラグインをお勧めします
  • コードの解析と変更のためにhaskell-src-extが提案されました。これはスタイリッシュなhaskellがコードに小さな変更を加えるために使用するものであり、最善の策です。伝えられるところによると、Haskell 2010のほとんど(すべて?)と、すべてではありませんが多くのGHC拡張機能をカバーしており、私が提供した最初のソリューションが気に入らない場合は、おそらく最善の策です。

私の知る限り、GHC-APIはGHC互換コードと完全に互換性のある唯一のものですが、かなり複雑で、十分に文書化されておらず、GHCバージョンからGHCバージョンに変更される可能性が高いか、少なくともそうなる見込みはありません。私の限られた経験から、同じである。モジュールを真ん中に置くことを提案しました。これは、優れたテストカバレッジで作業を開始するのが最も早いようで、新しい知識の量が最も少なく、質問から選んだ要件を満たしているためです。

于 2013-01-24T02:34:08.250 に答える