同じ署名で複数のモジュールで定義された関数を動的に呼び出す方法
-
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を印刷します run1
と run2
. 。最後の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.hs
と Nucleotide.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