Comment appeler dynamiquement une fonction définie dans plusieurs modules de la même signature

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

  •  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

Était-ce utile?

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top