如何动态调用在同一签名中多个模块中定义的函数
-
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定义大列表,或者只需在运行时加载相应的模块而无需将每个模块分开为不同的共享库即可。
基于 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。似乎未提取导入但未引用的功能...
解决方案
我曾经有类似的问题 列表中的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
不隶属于 StackOverflow