Как динамически вызвать функцию, которая определена в нескольких модулях в одной и той же подписи
-
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 или просто загрузить соответствующий модуль по мере необходимости во время выполнения без необходимости разделения каждого модуля на разные общие библиотеки.
На основе ЭпсилонхалбеОтвет, я провел некоторое исследование:
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. Кажется, что функции импортируются, но не ссылаются, не будут извлечены ...
Решение
Однажды у меня была похожая проблема модуль загрузки Haskell в списке Может, это помогает.
Вы можете создать список функций с помощью REGEXP и выбрать функцию по пользователю в этом списке. Я не знаю, нужно ли вам импортировать все «пробеги», квалифицированные вручную или если вы можете
import R*.hs (run)
Я бы предпочел написать один файл с 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*
В одном файле, и там я сгенерировал список всех функций запуска, которые сразу же работали - взглянуть на мой Нуклеотидный проект особенно файлы 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
Функции живут в разных модулях? Если вы можете поместить их все в один модуль, вы можете сделать 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