6

私は非常に頻繁に行う次のボイラープレートを持っており、削除したいと考えています。次のようになります。

type Configured = ReaderT Config

doSomething :: Configured IO Data
doSomething = do
   getMeta <- asks getMetaData
   meta <- liftIO getMeta

それを次のように減らしたいと思います。

doSomething = do
    meta <- find getMetaData

残念ながら、モナド変換子についてはまだ完全には理解できていません。の型はfind何ですか? ですか(Config -> IO Result) -> Result?どうやって書くの?

モナドトランスフォーマーをgrokするのに役立つヒント/説明は大歓迎です。

ありがとう!

4

1 に答える 1

11

これはかなり機械的な方法で行うことができます。元のコードから始めましょう。

doSomething = do
    getMeta <- asks getMetaData
    meta <- liftIO getMeta
    ...

3 番目のモナドの法則を使用して、抽出したい部分を独自の do ブロックに移動することができます。

doSomething = do
    meta <- do getMeta <- asks getMetaData
               liftIO getMeta
    ...

次に、その部分式を抽出して名前を付けます。

findMetaData = do getMeta <- asks getMetaData
                  liftIO getMeta

doSomething = do
    meta <- findMetaData
    ...

getMetaData最後に、明示的な参照をパラメーターに置き換えて一般化しましょう。

find something = do x <- asks something
                    liftIO x

doSomething = do
     meta <- find getMetaData
     ...

これで、それを GHCi にロードして、型を推測するように依頼できます。

*Main> :t find 
find :: (MonadReader r m, MonadIO m) => (r -> IO b) -> m b

必要に応じて、少しクリーンアップしてダミーの名前を削除することもできますx

find something = ask >>= liftIO . something

これを行うために、 do-notationの定義asks脱糖規則を使用しました。

于 2011-11-16T22:33:47.587 に答える