Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the advantage of using the reader monad over passing the value directly?

Tags:

haskell

monads

I am trying to understand when to use the reader monad, but I haven’t found a good usage example. I am pretty sure I have limited knowledge on this topic.

Consider this example code:

import Control.Monad.Reader

data Env = Env
         { eInt :: Int
         , eStr :: String
         }

calculateR :: Reader Env Int
calculateR = do
    e <- ask
    return $ eInt e

calculate :: Env -> Int
calculate = eInt

main :: IO ()
main = do
    let env = Env { eInt = 1, eStr = "hello"}
    let a = runReader calculateR env
    let b = calculate env
    print (a,b)

If I want to pass around the global Env to be able to access it from any function, should I use the reader monad for this purpose?

In comparison to just passing the Env directly to the function, is there any benefit?

If I understand correctly, both calculate and calculateR are pure (in the sense that they won't be able to make any change to env), and both have Env in their type signature telling that they might read the value form env to use in their computation.

like image 800
wizzup Avatar asked Mar 14 '17 07:03

wizzup


1 Answers

The advantage comes when you want to compose two functions.

f :: a -> Reader Env b
g :: b -> Reader Env c

g <=< f

or in the do notation

\a -> do
    b <- f a
    g b

vs

f :: a -> Env -> b
g :: b -> Env -> c

\a e -> g (f a e) e

in the latter you have to keep passing the environment around by yourself, while the monad instance provides you with a composition that does it for you. The manual composition will quickly become unnecessarily verbose and complex as more functions are involved.

Reader then provides you with local too.

like image 94
jakubdaniel Avatar answered Oct 17 '22 03:10

jakubdaniel