同じ署名で複数のモジュールで定義された関数を動的に呼び出す方法

StackOverflow https://stackoverflow.com/questions/7306578

  •  25-10-2019
  •  | 
  •  

質問

私は多くの機能(たとえば、100歳以上)を定義しましたが、それぞれが特定の作業を行いますが、同じ署名を使用しています。それは次のようなものです:

module R001 (run) where run = <do-...>
module R002 (run) where run = <do-...>

私がしたいのは、実際の「実行」をユーザー入力として提供することです。

main = do
         runWith $ read $ getLine
       where
         runWith :: Int -> IO ()
         runWith n = R<n-padded-with-0>.run

現在、資格のあるすべてのモジュールをインポートし、すべてを配置します runのリストに [Maybe (IO())], 、だからこれは機能します:

runWith n = case Rs !! (read $ getLine) of 
              Just run -> run
              Nothing -> undefined

しかし、 n 成長して、私は継続的に大きなリストを維持する必要があります。

TemplateHaskellを使用して大きなリストを定義する方法はありますか、それとも各モジュールを異なる共有ライブラリに分離することなく、実行時に必要に応じて対応するモジュールをロードするだけです。


に基づく epsilonhalbe答え、私はいくつかの研究をしました:

import R1 (run1)
import R2 (run2)

test = $(functionExtractor "^run")

main :: IO ()
main = do
         putStrLn $ show $ length $ test
         run1 -- remove on second attempt
         run2 -- remove on second attempt

このコードブロックは、の結果に続いて2を印刷します run1run2. 。最後の2行を削除すると、0を印刷するだけです。インポートされているが参照されていない関数は抽出されないようです...

役に立ちましたか?

解決

私はかつて同様の問題を抱えていました リスト内のHaskellロードモジュール 多分これは助けになります。

regexpを使用して関数のリストを作成し、そのリストからuserinpputによる関数を選択できます。手作業で資格のあるすべての「実行」をインポートする必要があるかどうか、またはできるかどうかはわかりません

import R*.hs (run)

1つのファイルを書きたいです run1 = …, run2 = … すべての実行のリストと、同じタイプの署名を持つ関数のリストから関数を取る関数選択関数を生成します。

{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.Extract
import myRunFunctions

main = do
     let listOfRuns = $(functionExtractor "^run")
     putStrLn "please choose a run"
     putStrLn $ show listOfRuns
     let run = runWith $ read $ getLine
     run
   where
     runWith n = listOfRuns !! n

注意:私は持っています いいえ このコードを実行するこれは、Haskell構文に入れられた思考のストリームです

これが役立つことを願っています


編集後:
私の例では、私はすべてを書きました run* 1つのファイルで、すべての実行機能のリストを生成しました。 ヌクレオチドプロジェクト 特にファイル Rules.hsNucleotide.hs.

Runs.hs

module Runs where
import Language.Haskell.Extract

listOfRuns = map snd $(functionExtractor "^run")

run1 = …
run2 = …

Main.hs

import Runs

main = do
     putStrLn "please choose a run"
     putStrLn $ show listOfRuns
     let run = runWith $ read $ getLine
     run
  where
    runWith n = listOfRuns !! n

助けてくれてうれしいです

他のヒント

違うことは絶対に重要ですか? run 関数はさまざまなモジュールに住んでいますか?それらをすべて1つのモジュールに入れることができれば、あなたは作ることができます run の関数になります Int (また Integer 必要に応じて)。

module AllMyCircuits where
run 0 = {- do blah blah blah -}
run 1 = {- do blah blah blah -}
run 2 = {- do yikes -}

module Main where
import AllMyCircuits
main = readLn >>= run
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top