4

についての紹介によると、ReaderT次のものしか見つかりません。

ReaderT Env IO String

そして、それは意味します

...is a computation which involves reading values from some environment 
of type Env (the semantics of Reader, the base monad) and performing some 
IO in order to give a value of type String.

したがって、実行順序は次のようになります

1. ( Already has ) some environment values          -- ReaderT Env
2. Do `IO` accroding to these pre-existing values   -- IO a
3. Use the `IO a` values to do more computations    -- IO b...z

これは、私たちのプログラムが環境としていくつかの既存の値を持っていることを要求しますが、ほとんどのプログラムはこれらの環境値をロードする必要があると思いました. データベース URL、デバッグ スイッチャーなどです。

したがって、逆の実行順序があり、Monad スタックによるとこれは違法です。

1. Do some `IO` to load environment settings        -- IO a first !!
2. Do more `IO` according to these settings         -- fill the env and do IO  

モナド スタックは次のようになります。

IOT Env ReaderT Env

IOモナドはモナド スタックのベース モナドになれないため、これは不正です。では、外部設定ファイルを使用してプログラムを初期化する適切な方法はありますか?

PS1。プログラムの一部として設定をxmonad コンパイルすることに気付きました。これが設定を「ロード」する唯一の方法かどうかはまだわかりません...

4

1 に答える 1

11

まず、モナド スタック内のモナドの順序は、実行するアクションの順序とは何の関係もありません。

第二に、ここではおそらくスタックさえ必要ありません。

構成を処理する典型的なプログラムは、次のように構成されています。

data Config = ...

readConfig :: IO Config
readConfig = do
    text <- readFile "~/.config"
    let config = ... -- do some parsing here
    return config


meat :: Reader Config Answer
meat = do
    -- invoke some operations, which get config automatically through the
    -- monad

main = do
    config <- readConfig
    let answer = runReader meat config
    print answer

モナド スタックが必要になるのは、meatそれ自体が何らかの IO を実行する必要がある場合のみです (構成の読み取りは別として)。その場合、あなたは持っているでしょう

meat :: ReaderT Config IO Answer
meat = ...

main = do
    config <- readConfig
    answer <- runReaderT meat config
    print answer
于 2012-07-23T08:42:59.140 に答える