<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!--Rendered using the Haskell Html Library v0.2--> <HTML ><HEAD ><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8" ><TITLE >Control.Monad.Reader</TITLE ><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css" ><SCRIPT SRC="haddock-util.js" TYPE="text/javascript" ></SCRIPT ><SCRIPT TYPE="text/javascript" >window.onload = function () {setSynopsis("mini_Control-Monad-Reader.html")};</SCRIPT ></HEAD ><BODY ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="topbar" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD ><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" " ></TD ><TD CLASS="title" >mtl-1.1.0.2: Monad transformer library</TD ><TD CLASS="topbut" ><A HREF="index.html" >Contents</A ></TD ><TD CLASS="topbut" ><A HREF="doc-index.html" >Index</A ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="modulebar" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD ><FONT SIZE="6" >Control.Monad.Reader</FONT ></TD ><TD ALIGN="right" ><TABLE CLASS="narrow" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="infohead" >Portability</TD ><TD CLASS="infoval" >non-portable (multi-param classes, functional dependencies)</TD ></TR ><TR ><TD CLASS="infohead" >Stability</TD ><TD CLASS="infoval" >experimental</TD ></TR ><TR ><TD CLASS="infohead" >Maintainer</TD ><TD CLASS="infoval" >libraries@haskell.org</TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="section4" ><B >Contents</B ></TD ></TR ><TR ><TD ><DL ><DT ><A HREF="#1" >Example 1: Simple Reader Usage </A ></DT ><DT ><A HREF="#2" >Example 2: Modifying Reader Content With <TT >local</TT > </A ></DT ><DT ><A HREF="#3" >Example 3: <TT >ReaderT</TT > Monad Transformer </A ></DT ></DL ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" >Description</TD ></TR ><TR ><TD CLASS="doc" ><DL ><DT >Computation type:</DT ><DD > Computations which read values from a shared environment. </DD ><DT >Binding strategy:</DT ><DD > Monad values are functions from the environment to a value. The bound function is applied to the bound value, and both have access to the shared environment. </DD ><DT >Useful for:</DT ><DD > Maintaining variable bindings, or other shared environment. </DD ><DT >Zero and plus:</DT ><DD > None. </DD ><DT >Example type:</DT ><DD > <TT ><TT ><A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A ></TT > [(String,Value)] a</TT > </DD ></DL ><P >The <TT ><A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A ></TT > monad (also called the Environment monad). Represents a computation, which can read values from a shared environment, pass values from function to function, and execute sub-computations in a modified environment. Using <TT ><A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A ></TT > monad for such computations is often clearer and easier than using the Control.Monad.State.State monad. </P ><P >Inspired by the paper /Functional Programming with Overloading and Higher-Order Polymorphism/, Mark P Jones (<A HREF="http://web.cecs.pdx.edu/~mpj/" >http://web.cecs.pdx.edu/~mpj/</A >) Advanced School of Functional Programming, 1995. </P ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" >Synopsis</TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="decl" >module <A HREF="Control-Monad-Reader-Class.html" >Control.Monad.Reader.Class</A ></TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >newtype</SPAN > <A HREF="#t%3AReader" >Reader</A > r a = <A HREF="#v%3AReader" >Reader</A > {<TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="recfield" ><A HREF="#v%3ArunReader" >runReader</A > :: r -> a</TD ></TR ></TABLE >}</TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><A HREF="#v%3AmapReader" >mapReader</A > :: (a -> b) -> <A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r a -> <A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r b</TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><A HREF="#v%3AwithReader" >withReader</A > :: (r' -> r) -> <A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r a -> <A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r' a</TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >newtype</SPAN > <A HREF="#t%3AReaderT" >ReaderT</A > r m a = <A HREF="#v%3AReaderT" >ReaderT</A > {<TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="recfield" ><A HREF="#v%3ArunReaderT" >runReaderT</A > :: r -> m a</TD ></TR ></TABLE >}</TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><A HREF="#v%3AmapReaderT" >mapReaderT</A > :: (m a -> n b) -> <A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > w m a -> <A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > w n b</TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><A HREF="#v%3AwithReaderT" >withReaderT</A > :: (r' -> r) -> <A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m a -> <A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r' m a</TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" >module <A HREF="../base/Control-Monad.html" >Control.Monad</A ></TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" >module <A HREF="../base/Control-Monad-Fix.html" >Control.Monad.Fix</A ></TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" >module <A HREF="Control-Monad-Trans.html" >Control.Monad.Trans</A ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" >Documentation</TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" >module <A HREF="Control-Monad-Reader-Class.html" >Control.Monad.Reader.Class</A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >newtype</SPAN > <A NAME="t:Reader" ><A NAME="t%3AReader" ></A ></A ><B >Reader</B > r a </TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="ndoc" ><P >The parameterizable reader monad. </P ><P >The <TT >return</TT > function creates a <TT >Reader</TT > that ignores the environment, and produces the given value. </P ><P >The binding operator <TT >>>=</TT > produces a <TT >Reader</TT > that uses the environment to extract the value its left-hand side, and then applies the bound function to that value in the same environment. </P ></TD ></TR ><TR ><TD CLASS="section4" >Constructors</TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="5" CELLPADDING="0" ><TR ><TD CLASS="arg" ><A NAME="v:Reader" ><A NAME="v%3AReader" ></A ></A ><B >Reader</B ></TD ><TD CLASS="rdoc" ></TD ></TR ><TR ><TD CLASS="body" COLSPAN="2" ><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0" ><TR ><TD CLASS="arg" ><A NAME="v:runReader" ><A NAME="v%3ArunReader" ></A ></A ><B >runReader</B > :: r -> a</TD ><TD CLASS="rdoc" ><P >Runs <TT >Reader</TT > and extracts the final value from it. To extract the value apply <TT >(runReader reader)</TT > to an environment value. Parameters: </P ><UL ><LI > A <TT >Reader</TT > to run. </LI ><LI > An initial environment. </LI ></UL ></TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="section4" ><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:Reader')" ALT="show/hide" > Instances</TD ></TR ><TR ><TD CLASS="body" ><DIV ID="i:Reader" STYLE="display:block;" ><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0" ><TR ><TD CLASS="decl" ><A HREF="Control-Monad-Reader-Class.html#t%3AMonadReader" >MonadReader</A > r (<A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="../base/Control-Monad.html#t%3AMonad" >Monad</A > (<A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="../base/Control-Monad.html#t%3AFunctor" >Functor</A > (<A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="../base/Control-Monad-Fix.html#t%3AMonadFix" >MonadFix</A > (<A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r)</TD ></TR ></TABLE ></DIV ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><A NAME="v:mapReader" ><A NAME="v%3AmapReader" ></A ></A ><B >mapReader</B > :: (a -> b) -> <A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r a -> <A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r b</TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><A NAME="v:withReader" ><A NAME="v%3AwithReader" ></A ></A ><B >withReader</B > :: (r' -> r) -> <A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r a -> <A HREF="Control-Monad-Reader.html#t%3AReader" >Reader</A > r' a</TD ></TR ><TR ><TD CLASS="doc" >A more general version of <TT ><A HREF="Control-Monad-Reader-Class.html#v%3Alocal" >local</A ></TT >. </TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >newtype</SPAN > <A NAME="t:ReaderT" ><A NAME="t%3AReaderT" ></A ></A ><B >ReaderT</B > r m a </TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="ndoc" >The reader monad transformer. Can be used to add environment reading functionality to other monads. </TD ></TR ><TR ><TD CLASS="section4" >Constructors</TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="5" CELLPADDING="0" ><TR ><TD CLASS="arg" ><A NAME="v:ReaderT" ><A NAME="v%3AReaderT" ></A ></A ><B >ReaderT</B ></TD ><TD CLASS="rdoc" ></TD ></TR ><TR ><TD CLASS="body" COLSPAN="2" ><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0" ><TR ><TD CLASS="arg" ><A NAME="v:runReaderT" ><A NAME="v%3ArunReaderT" ></A ></A ><B >runReaderT</B > :: r -> m a</TD ><TD CLASS="rdoc" ></TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="section4" ><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:ReaderT')" ALT="show/hide" > Instances</TD ></TR ><TR ><TD CLASS="body" ><DIV ID="i:ReaderT" STYLE="display:block;" ><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0" ><TR ><TD CLASS="decl" ><A HREF="Control-Monad-Writer-Class.html#t%3AMonadWriter" >MonadWriter</A > w m => <A HREF="Control-Monad-Writer-Class.html#t%3AMonadWriter" >MonadWriter</A > w (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="Control-Monad-State-Class.html#t%3AMonadState" >MonadState</A > s m => <A HREF="Control-Monad-State-Class.html#t%3AMonadState" >MonadState</A > s (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="../base/Control-Monad.html#t%3AMonad" >Monad</A > m => <A HREF="Control-Monad-Reader-Class.html#t%3AMonadReader" >MonadReader</A > r (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="Control-Monad-Error-Class.html#t%3AMonadError" >MonadError</A > e m => <A HREF="Control-Monad-Error-Class.html#t%3AMonadError" >MonadError</A > e (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="Control-Monad-Trans.html#t%3AMonadTrans" >MonadTrans</A > (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="../base/Control-Monad.html#t%3AMonad" >Monad</A > m => <A HREF="../base/Control-Monad.html#t%3AMonad" >Monad</A > (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="../base/Control-Monad.html#t%3AMonad" >Monad</A > m => <A HREF="../base/Control-Monad.html#t%3AFunctor" >Functor</A > (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="../base/Control-Monad-Fix.html#t%3AMonadFix" >MonadFix</A > m => <A HREF="../base/Control-Monad-Fix.html#t%3AMonadFix" >MonadFix</A > (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="../base/Control-Monad.html#t%3AMonadPlus" >MonadPlus</A > m => <A HREF="../base/Control-Monad.html#t%3AMonadPlus" >MonadPlus</A > (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="Control-Monad-Trans.html#t%3AMonadIO" >MonadIO</A > m => <A HREF="Control-Monad-Trans.html#t%3AMonadIO" >MonadIO</A > (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ><TR ><TD CLASS="decl" ><A HREF="Control-Monad-Cont-Class.html#t%3AMonadCont" >MonadCont</A > m => <A HREF="Control-Monad-Cont-Class.html#t%3AMonadCont" >MonadCont</A > (<A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m)</TD ></TR ></TABLE ></DIV ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><A NAME="v:mapReaderT" ><A NAME="v%3AmapReaderT" ></A ></A ><B >mapReaderT</B > :: (m a -> n b) -> <A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > w m a -> <A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > w n b</TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><A NAME="v:withReaderT" ><A NAME="v%3AwithReaderT" ></A ></A ><B >withReaderT</B > :: (r' -> r) -> <A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r m a -> <A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A > r' m a</TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" >module <A HREF="../base/Control-Monad.html" >Control.Monad</A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" >module <A HREF="../base/Control-Monad-Fix.html" >Control.Monad.Fix</A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" >module <A HREF="Control-Monad-Trans.html" >Control.Monad.Trans</A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" ><A NAME="1" ><A NAME="1" >Example 1: Simple Reader Usage </A ></A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="doc" ><P >In this example the <TT >Reader</TT > monad provides access to variable bindings. Bindings are a Map of integer variables. The variable <TT >count</TT > contains number of variables in the bindings. You can see how to run a Reader monad and retrieve data from it with <TT ><A HREF="Control-Monad-Reader.html#v%3ArunReader" >runReader</A ></TT >, how to access the Reader data with <TT ><A HREF="Control-Monad-Reader-Class.html#v%3Aask" >ask</A ></TT > and <TT ><A HREF="Control-Monad-Reader-Class.html#v%3Aasks" >asks</A ></TT >. </P ><PRE > type Bindings = Map String Int; -- Returns True if the "count" variable contains correct bindings size. isCountCorrect :: Bindings -> Bool isCountCorrect bindings = runReader calc_isCountCorrect bindings -- The Reader monad, which implements this complicated check. calc_isCountCorrect :: Reader Bindings Bool calc_isCountCorrect = do count <- asks (lookupVar "count") bindings <- ask return (count == (Map.size bindings)) -- The selector function to use with 'asks'. -- Returns value of the variable with specified name. lookupVar :: String -> Bindings -> Int lookupVar name bindings = fromJust (Map.lookup name bindings) sampleBindings = Map.fromList [("count",3), ("1",1), ("b",2)] main = do putStr $ "Count is correct for bindings " ++ (show sampleBindings) ++ ": "; putStrLn $ show (isCountCorrect sampleBindings); </PRE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" ><A NAME="2" ><A NAME="2" >Example 2: Modifying Reader Content With <TT >local</TT > </A ></A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="doc" ><P >Shows how to modify Reader content with <TT ><A HREF="Control-Monad-Reader-Class.html#v%3Alocal" >local</A ></TT >. </P ><PRE >calculateContentLen :: Reader String Int calculateContentLen = do content <- ask return (length content); -- Calls calculateContentLen after adding a prefix to the Reader content. calculateModifiedContentLen :: Reader String Int calculateModifiedContentLen = local ("Prefix " ++) calculateContentLen main = do let s = "12345"; let modifiedLen = runReader calculateModifiedContentLen s let len = runReader calculateContentLen s putStrLn $ "Modified 's' length: " ++ (show modifiedLen) putStrLn $ "Original 's' length: " ++ (show len) </PRE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" ><A NAME="3" ><A NAME="3" >Example 3: <TT >ReaderT</TT > Monad Transformer </A ></A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="doc" ><P >Now you are thinking: 'Wow, what a great monad! I wish I could use Reader functionality in MyFavoriteComplexMonad!'. Don't worry. This can be easy done with the <TT ><A HREF="Control-Monad-Reader.html#t%3AReaderT" >ReaderT</A ></TT > monad transformer. This example shows how to combine <TT >ReaderT</TT > with the IO monad. </P ><PRE >-- The Reader/IO combined monad, where Reader stores a string. printReaderContent :: ReaderT String IO () printReaderContent = do content <- ask liftIO $ putStrLn ("The Reader Content: " ++ content) main = do runReaderT printReaderContent "Some Content" </PRE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="botbar" >Produced by <A HREF="http://www.haskell.org/haddock/" >Haddock</A > version 2.4.2</TD ></TR ></TABLE ></BODY ></HTML >