Skip to content

Instantly share code, notes, and snippets.

@raichoo
Created August 26, 2016 22:56
Show Gist options
  • Save raichoo/5e1c3942d2d199d8936d03cd82ce90ec to your computer and use it in GitHub Desktop.
Save raichoo/5e1c3942d2d199d8936d03cd82ce90ec to your computer and use it in GitHub Desktop.
Example where Reader is helpful.
module Main where
-- ReaderT is a little more useful as an example
-- think of it as Reader that can also do IO using
-- the `lift` function.
import Control.Monad.Reader
import Text.Printf
type Connection = ()
type Name = String
type Age = Int
data Person = Person
{ personName :: Name
, personAge :: Age
} deriving Show
mkConn :: IO Connection
mkConn = return ()
-- passing the connection explicitly
selectByName :: Connection -> Name -> IO Person
selectByName conn name = do
printf "Selecting person for name %s with connection %s\n" name (show conn)
return (Person "raichoo" 35)
selectByAge :: Connection -> Age -> IO [Person]
selectByAge conn age = do
printf "Selecting persons for age %d with connection %s\n" age (show conn)
return []
-- ReaderT example. Connection is passed automatically by ReaderT.
type DB = ReaderT Connection IO
selectByName' :: Name -> DB Person
selectByName' name = do
conn <- ask
lift (printf "Selecting person for name %s with connection %s\n" name (show conn))
return (Person "raichoo" 35)
selectByAge' :: Age -> DB [Person]
selectByAge' age = do
conn <- ask
lift (printf "Selecting persons for age %d with connection %s\n" age (show conn))
return []
main :: IO ()
main = do
conn <- mkConn
-- this is sort of clunky since we have to pass the connection explicitly
person <- selectByName conn "raichoo"
persons <- selectByAge conn (personAge person)
-- pass Connection to the ReaderT and it passes it automatically
flip runReaderT conn $ do
person <- selectByName' "raichoo"
persons <- selectByAge' (personAge person)
return ()
return ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment