Readerモナド
グローバル定数を持ち回っている感じ
何処からでもアクセスできるけど、変更はできない
昔はEnvironment Monadと呼ばれていた
らしい
型の定義
hsnewtype Reader env a = Reader { runReader :: env -> a }
env
は参照したい環境の型
グローバル引数っぽく扱う値の型
実装
hsinstance Monad (Reader env) where
return a = Reader (\_ -> a)
Reader f >>= g = Reader $ (\e -> runReader (g (f e)) e)
Maybe a
がモナドであるのと同じように Reader r
がモナド
bindの定義は以下のようにも書ける
m >>= f = Reader $ \env -> runReader (f (runReader m env)) env
全ての関数が共通の情報を読むから
do式を用いた例
hs-- kは普通の関数
k :: Int -> Int
k = do -- k 3を実行したときの例
a <- (* 2) -- a = 3*2 = 6
b <- (+ 10) -- b = 3+10 = 13
return $ a * b -- 13*6 = 78
k 3
を実行した時
*2
も +10
も return $ a * b
も引数 3
を読んでいる
ただし最後のreturnは引き数を読んではいるが、無視している
関数もなどの return
の定義を参照したらわかる
ask :: MonadReader r m => m r
状態をgetするアクション
runReader :: Reader r a -> r -> a
r
が状態、環境
runStateの型は runState :: State s a -> s -> (a, s)
runReaderの返り値には状態が含まれないことがわかるね
reader :: MonadReader r m => (r -> a) -> m a
関数からReaderモナドを生成する
local :: MonadReader r m => (r -> r) -> m a -> m a
asks :: MonadReader r m => (r -> a) -> m a
引数の関数を、環境に適応した結果、を返す
ユースケース
プログラム内でconfigファイルを参照する
参考