功能编程中的模块初始化



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

这如何在函数范式中完成,例如在像Haskell这样的语言中?

编辑:

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

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

data Options = {- ... -}
doMyProgram :: Options -> IO ()
myModule'sConstantA :: Options -> A
myModule'sConstantB :: Options -> B

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

严格来说,这并非不可能,可能不应该这样做

import System.Environment
import System.IO.Unsafe
firstArg :: String
firstArg = head $ unsafePerformIO getArgs
{-# NOINLINE firstArg #-}
main = putStrLn firstArg

请注意"不安全"一词在这六行代码段中出现的次数。

它既肮脏又恶心,但 IMO,这种范式有一些有效的用例,全局常量初始化就是其中之一。例如,我用它来加载游戏中的关卡文件。

最新更新