Skip to content

Instantly share code, notes, and snippets.

@mzvonar
Created August 4, 2021 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mzvonar/3a7276d46f0509880ae255003b950e3a to your computer and use it in GitHub Desktop.
Save mzvonar/3a7276d46f0509880ae255003b950e3a to your computer and use it in GitHub Desktop.
Example of Reader context not working in Free interpreter
module Test.Free where
import Prelude
import Control.Monad.Free (Free, liftF, foldFree)
import Control.Monad.Reader (ReaderT, ask, lift, local, runReaderT)
import Effect (Effect)
import Effect.Console as Console
data Filter = All | Info | Error
derive instance Eq Filter
instance Show Filter where
show All = "All"
show Info = "Info"
show Error = "Error"
data ReportF a
= SetFilter Filter a
| ShowFilter a
derive instance Functor ReportF
type Report = Free ReportF
type Env = Filter
type Output a = ReaderT Env Effect a
setFilter :: Filter -> Report Unit
setFilter a = liftF $ SetFilter a unit
showFilter :: Report Unit
showFilter = liftF $ ShowFilter unit
renderToConsole :: Report Unit -> Effect Unit
renderToConsole r = runReaderT (interpret r) All
interpret :: Report ~> Output
interpret = foldFree go
where
go :: ReportF ~> Output
go = case _ of
SetFilter a next -> do
lift $ Console.log $ "Setting filter to " <> show a
local (const a) do
filter <- ask
-- The filter here is set properly
lift $ Console.log $ "Inside the setFilter fn the filter is " <>show filter
-- Filter inside this next computation is lost
pure next
ShowFilter next -> do
filter <- ask
lift $ Console.log $ "Filter is now " <> show filter
pure next
showReport :: Report Unit
showReport = do
setFilter Error
showFilter
main :: Effect Unit
main = renderToConsole showReport
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment