2016-02-20 46 views
0

在一個項目中,我使用了一個包含我在項目其餘部分中使用的全局(常量初始化)的模塊。我選擇將它們放入模塊中以避免大量參數傳遞。問題是這個模塊必須在運行時用程序執行的參數進行初始化。函數式編程中的模塊初始化

這怎麼可能在功能範例中完成,例如像Haskell這樣的語言?

編輯:

更確切地說,我在命令式語言(ADA)的代碼,我的項目,這就是爲什麼我可以使用包含在運行時初始化變量的模塊,然後用作全局常量(用內聯getter)。但是,對函數式編程感興趣,我想知道如何在這個範例中獲得相同的結果;我的意思是在整個代碼的其餘部分(使用全局常量),模塊數據位於存儲器的數據部分,甚至能夠分別初始化模塊的不同「常量」等等的光特徵。

+4

你用['getArgs'](https://hackage.haskell.org/package/base-4.8.2.0/docs/System-Environment.html#v:getArgs)閱讀'main'中的參數並且把它們傳遞出去 - 如果你想變得很花哨,你可以使用Read/StateMonad(變形金剛)等等。當然你不能做的是在你的模塊中使用常量值 - 因爲這個問題是更多你必須更具體的真正廣泛 – Carsten

+0

一些功能性語言(但不是Haskell)提供了可以使用動態綁定進行初始化的一流模塊。 – dfeuer

+0

@Carsten你說得對,我編輯了我的帖子,有更具體的提問。 – olp

回答

4

如果程序的行爲取決於命令行上使用的參數,根本無法隱藏該事實 - 它必須出現在程序組件的類型中。最簡單的方法是寫

data Options = {- ... -} 

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

Options作爲參數傳遞給依賴於它的任何操作或價值。花式設計通常還會爲包含MonadReader Options M實例的程序定義一個自定義monad M以減少類型簽名的大小。

+0

感謝您的回答。正如你所說,沒有辦法讓選項全球后期初始化常量? Monad Reader的問題在於我不太瞭解它,但簽名更長,因爲它必須位於返回類型中。那麼數據在內存中的位置呢? (我編輯我的帖子更加準確) – olp

+0

@olp對不起,但即使你用不同的單詞提問相同的問題,答案也是一樣的。 –

0

嚴格來說,它不是不可能多達可能不應該做

import System.Environment 
import System.IO.Unsafe 

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

main = putStrLn firstArg 

請注意在該六行代碼段中出現了多少次「不安全」字樣。

這是骯髒和粗糙,但國際海事組織,這種範例有一些有效的用例,全局常量初始化是其中之一。例如,我用它來加載遊戲中的關卡文件。