功能编程中的模块初始化

时间:2016-02-20 16:22:48

标签: haskell functional-programming

在一个项目中,我使用的模块包含我在项目其余部分使用的全局(常量初始化)。我选择将它们放入模块中以避免大量参数传递。问题是该模块必须在运行时使用程序执行的参数进行初始化。

如何在功能范例中完成,例如像Haskell这样的语言?

编辑:

更确切地说,我用命令式语言(Ada)编写项目代码,这就是为什么我可以使用包含在运行时初始化的变量的模块,然后用作全局常量(带内联的getter)。但是,对函数式编程感兴趣,我想知道如何在这个范例中获得相同的结果;我的意思是在其余的代码中使用光签名(使用全局常量),在内存的数据部分中定位模块数据,甚至能够分别初始化模块的不同“常量”等。

2 个答案:

答案 0 :(得分:4)

如果程序的行为取决于命令行中使用的参数,则根本无法隐藏这一事实 - 它必须出现在程序组件的类型中。最简单的方法是编写

data Options = {- ... -}

doMyProgram :: Options -> IO ()
myModule'sConstantA :: Options -> A
myModule'sConstantB :: Options -> B

Options作为依赖于它的任何操作或值的参数。花哨的设计通常还为程序定义一个自定义monad M,其中包含MonadReader Options M实例以减少类型签名的大小。

答案 1 :(得分:0)

严格地说,它不是不可能,因为可能不应该

import System.Environment
import System.IO.Unsafe

firstArg :: String
firstArg = head $ unsafePerformIO getArgs
{-# NOINLINE firstArg #-}

main = putStrLn firstArg

请注意六行代码中出现“不安全”一词的次数。

它很脏且很粗糙,但IMO,这个范例有一些有效的用例,而全局常量初始化就是其中之一。例如,我用它来加载游戏中的关卡文件。