Comment appeler dynamiquement une fonction définie dans plusieurs modules de la même signature
-
25-10-2019 - |
Question
J'ai défini beaucoup de fonctions (par exemple, 100+), dont chacun font un travail spécifique, mais avec la même signature. C'est quelque chose comme:
module R001 (run) where run = <do-...>
module R002 (run) where run = <do-...>
Ce que je veux faire est de fournir le « run » réelle entrée de l'utilisateur, tels que:
main = do
runWith $ read $ getLine
where
runWith :: Int -> IO ()
runWith n = R<n-padded-with-0>.run
À l'heure actuelle, j'importer tous les modules qualifiés, et de mettre tous de l'run
dans une liste des [Maybe (IO())]
, ceci marche:
runWith n = case Rs !! (read $ getLine) of
Just run -> run
Nothing -> undefined
Mais comme le n
pousse, je dois maintenir continously une grande liste.
Est-il possible que je peux définir la grande liste à l'aide TemplateHaskell, ou tout simplement charger le module correspondant au besoin lors de l'exécution sans avoir à séparer chaque module dans différentes bibliothèques partagées.
Basé sur epsilonhalbe la réponse », je l'ai fait quelques recherches:
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
Ce bloc de code imprime 2 suivant les résultats de run1
et run2
. Si je supprime les deux dernières lignes, il imprime juste 0. Il semble que les fonctions importées mais non référencé ne sera pas ... Extrait
La solution
J'ai déjà eu un problème similaire module de charge haskell dans la liste peut-être cette aide.
Vous pouvez créer une liste de fonctions avec regexp et choisissez une fonction par userinput de cette liste. Je ne sais pas si vous devez importer tous les « runs » qualifiés à la main ou si vous pouvez
import R*.hs (run)
Je préfère écrire un fichier avec run1 = …
, run2 = …
et générer une liste de toutes les pistes et une fonction de sélecteur de fonction qui prend une fonction à partir d'une liste de fonctions avec la même signature de type.
{-# 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
Attention: je pas exécuter ce code est ce juste un courant de pensée mis dans la syntaxe haskell
J'espère que cela est utile
Après édition:
Dans mon exemple, je l'ai écrit tout run*
dans un seul fichier et il i généré la liste de toutes les fonctions d'exécution, qui a travaillé instantanément - un coup d'oeil à mon Nucleotide projet en particulier les fichiers Rules.hs
et 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
heureux d'être utile
Autres conseils
est-il absolument essentiel que les différentes fonctions de run
vivent dans différents modules? Si vous pouvez les mettre tous dans un seul module, vous pouvez faire run
une fonction d'un Int
(ou Integer
si vous préférez).
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