Я определил множество функций (скажем, более 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
. Если я удалю последние две строки, он просто напечатает 0. Кажется, что импортированные функции, на которые не ссылаются, не будут извлечены...