考虑这段代码:
isPrime primes' n = foldr (\p r -> p * p > n || (n `rem` p /= 0 && r)) True primes'
primes = 2 : filter (isPrime primes) [3..]
main = putStrLn $ show $ sum $ takeWhile (< 1000000) primes
Run Code Online (Sandbox Code Playgroud)
它计算低于一百万的所有素数之和.在我的机器上打印结果需要0.468秒.但如果定义isPrime和primes被提取到另一个模块,时间成本是1.23秒,它几乎慢3倍.
当然,我可以在任何需要的地方复制/粘贴定义,但我也很好奇为什么会发生这种情况,以及如何解决它.
[编辑]
我正在使用GHC 7.0.3(Windows 7 + MinGW).代码是用EclipseFP编写的(它使用Scion作为IDE后端),并内置到带有-O2标志的可执行文件中.
我也尝试在IDE之外构建包:
executable test
hs-source-dirs: src
main-is: Main.hs
build-depends: base >= 4
ghc-options: -O2
other-modules: Primes
executable test2
hs-source-dirs: …Run Code Online (Sandbox Code Playgroud) 我已经定义了很多函数(例如,100 +),每个函数都执行特定的工作但具有相同的签名.这就是:
module R001 (run) where run = <do-...>
module R002 (run) where run = <do-...>
Run Code Online (Sandbox Code Playgroud)
我想做的是提供实际的'run'作为用户输入,这样:
main = do
runWith $ read $ getLine
where
runWith :: Int -> IO ()
runWith n = R<n-padded-with-0>.run
Run Code Online (Sandbox Code Playgroud)
目前,我导入了所有合格的模块,并将所有的模块run放入一个列表中[Maybe (IO())],因此这有效:
runWith n = case Rs !! (read $ getLine) of
Just run -> run
Nothing -> undefined
Run Code Online (Sandbox Code Playgroud)
但随着n成长,我必须不断保持一个大的名单.
有没有什么办法可以使用TemplateHaskell定义大列表,或者只是在运行时根据需要加载相应的模块,而不必将每个模块分成不同的共享库.
基于epsilonhalbe的回答,我做了一些研究:
import R1 (run1)
import R2 (run2)
test = $(functionExtractor "^run")
main :: IO () …Run Code Online (Sandbox Code Playgroud) 我已经浏览了cabal Distribution.Simple*包,知道PreProcessor数据类型可用于定义自定义预处理器.但是提供的示例并不那么有用.我不知道如何调用预处理器.
目前,我只是在Setup.hs文件中定义自己的预处理器.
这个功能有完整的例子吗?
[已编辑]
检查我刚发现的这个邮件列表存档.但解决方案涉及从一种类型的文件(由该文件的扩展名标识)转换为另一种类型的文件.
我想要做的是将代码注入到.hs定义了自定义标记的现有文件中,例如
-- <inject point="foo">
-- extra Haskell code goes here
-- </inject>
Run Code Online (Sandbox Code Playgroud)