Reputation: 33
Is this even possible? I have a main that saves an Int (width) given by the user as a variable, but I need that variable in a bunch of other functions... Is there a way to do this other than adding 'width' as an argument to every function?
Upvotes: 2
Views: 84
Reputation: 2983
I'll show a simple example of reader monad usage.
This code:
area :: Double -> Double -> Double
area height width = height * width
main = do
width <- fmap read getLine
let result = area 42 width
print result
Becomes:
import Control.Monad.Reader
area :: MonadReader Double m => Double -> m Double
area height = do
width <- ask
return (width * height)
main :: IO ()
main = do
width <- fmap read getLine
let result = runReader (area 42) width
print result
This seems more complicated, but it's actually quite nice when you have a lot of "configuration" parameters to pass around.
import Control.Monad.Reader
data Config = Config { width :: Double, color :: String, etc :: String }
area :: MonadReader Config m => Double -> m Double
area height = do
w <- asks width
return (w * height)
main :: IO ()
main = do
w <- fmap read getLine
c <- undefined -- todo get color param
e <- undefined -- todo get etc param
let result = runReader (area 42) (Config w c e)
print result
Upvotes: 3