Skip to content

Instantly share code, notes, and snippets.

@rlucha
Last active January 19, 2022 13:40
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save rlucha/696ca604c9744ad11aff7d46b1706de7 to your computer and use it in GitHub Desktop.
Save rlucha/696ca604c9744ad11aff7d46b1706de7 to your computer and use it in GitHub Desktop.
module Main where
import Prelude
import Control.Monad.Reader (Reader, runReader, ReaderT(..), runReaderT, ask, class MonadAsk)
import Effect (Effect)
import Effect.Class (class MonadEffect, liftEffect)
import Effect.Console (log)
---------------------------------------------------------
-- 01 no Reader
---------------------------------------------------------
data Config = Config String
getConfig :: Config -> String
getConfig (Config c) = c
main01 :: Effect Unit
main01 = do
log $ getConfig config
where config = (Config " ***** foo ***** ")
---------------------------------------------------------
-- 02 with Reader
-- getConfigR doesn't need to be passed config directly
-- as it is within the context of the monad
---------------------------------------------------------
getConfigR :: Reader Config String
getConfigR = do
config <- ask
pure (getConfig config)
main02 :: Effect Unit
main02 = do
log $ runReader getConfigR config
where config = (Config " ***** fooR ***** ")
---------------------------------------------------------
-- 03 with ReaderT
-- Now we can combine a side effect while also asking for the config
---------------------------------------------------------
getConfigRT :: ReaderT Config Effect String
getConfigRT = do
config <- ask
liftEffect (log "side effect!")
pure (getConfig config)
main03 :: Effect Unit
main03 = do
r <- runReaderT getConfigRT config
log r
where config = (Config " ***** fooR ***** ")
---------------------------------------------------------
-- 04 with App as a newType
-- We start creating now a App Monad with the behaviours we want
---------------------------------------------------------
newtype App a = App (ReaderT Config Effect a)
derive newtype instance bindApp ∷ Bind App
derive newtype instance applicativeApp ∷ Applicative App
derive newtype instance monadAskApp :: MonadAsk Config App
derive newtype instance monadEffectApp :: MonadEffect App
getConfigApp :: App String
getConfigApp = do
config <- ask
liftEffect (log "side effect!")
pure (getConfig config)
runApp :: forall a. App a -> Config -> Effect a
runApp (App readerT) c = runReaderT readerT c
main04 :: Effect Unit
main04 = do
r <- runApp getConfigApp config
log r
where config = (Config " ***** fooR ***** ")
---------------------------------------------------------
-- 05 with constrains
-- Now we uncouple the functions from the app by
-- declaring what are the characteristics of the monad
-- where this function is going to execute, instead of the actual monad
-- so that we can add new things without changing the App monad types everywhere
---------------------------------------------------------
newtype AppC a = AppC (ReaderT Config Effect a)
derive newtype instance bindAppC ∷ Bind AppC
derive newtype instance applicativeAppC ∷ Applicative AppC
derive newtype instance monadAskAppC :: MonadAsk Config AppC
derive newtype instance monadEffectAppC :: MonadEffect AppC
getConfigAppC :: forall m. MonadEffect m => MonadAsk Config m => m Unit
getConfigAppC = do
config <- ask
liftEffect (log (getConfig config))
runAppC :: forall a. AppC a -> Config -> Effect a
runAppC (AppC readerT) c = runReaderT readerT c
main05 :: Effect Unit
main05 = do
runAppC getConfigAppC config
where config = (Config " Show me ")
@JordanMartinez
Copy link

Mind adding some highlighting to this gist by adding the ".purs" file extension?

@rlucha
Copy link
Author

rlucha commented Jan 29, 2019

Sure :)

@JordanMartinez
Copy link

Thanks. That makes it a bit easier to read.

I'm linking to this gist in my learning repo here: https://github.com/JordanMartinez/purescript-jordans-reference
(JordanMartinez/purescript-jordans-reference#234)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment