I've defined a lot of functions (say, 100+), each of which do a specific work but with the same signature. That is something like:
module R001 (run) where run = <do-...>
module R002 (run) where run = <do-...>
What I wanna do is to provide the actual 'run' as user input, such that:
main = do
runWith $ read $ getLine
wher开发者_开发知识库e
runWith :: Int -> IO ()
runWith n = R<n-padded-with-0>.run
Currently, I import all modules qualified, and put all the run
's into a list of [Maybe (IO())]
, so this works:
runWith n = case Rs !! (read $ getLine) of
Just run -> run
Nothing -> undefined
But as the n
grows, I have to continously maintain a big list.
Is there any way I can define the big list using TemplateHaskell, or just load the corresponding module as needed at runtime without having to seperate each module into different shared libraries.
Based on epsilonhalbe's answer, I did some research:
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
This block of code prints 2 following the results of run1
and run2
. If I remove the last two lines, it just prints 0. It seems that functions imported but not referenced won't be extracted ...
I once had a similar problem haskell load module in list maybe this helps.
You can create a list of functions with regexp and choose a function by userinput from that list. I don't know if you have to import all "runs" qualified by hand or if you can
import R*.hs (run)
i would rather write one file with run1 = …
, run2 = …
and generate a list of all runs and a function chooser function which takes a function from a list of functions with the same type signature.
{-# 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: I have not run this code this is just a stream of thought put in haskell syntax
i hope this is helpful
After edit:
In my example i wrote all run*
in one file and there i generated the list of all run functions, which worked instantly - have a look at my Nucleotide Project especially the files Rules.hs
and 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
happy to be helpful
Is it absolutely critical that the different run
functions live in different modules? If you can put them all in one module, you could make run
be a function of an Int
(or Integer
if you prefer).
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
精彩评论