Skip to content

Instantly share code, notes, and snippets.

@felix-lipski
Last active June 12, 2022 19:07
Show Gist options
  • Save felix-lipski/778d10396e2019e7cbd700fbde717bcb to your computer and use it in GitHub Desktop.
Save felix-lipski/778d10396e2019e7cbd700fbde717bcb to your computer and use it in GitHub Desktop.
Simple example of interleaving State and IO in Polysemy
{-# LANGUAGE TemplateHaskell, LambdaCase, BlockArguments, GADTs, FlexibleContexts, TypeOperators, DataKinds, PolyKinds, ScopedTypeVariables, TypeApplications #-}
import Polysemy
import Polysemy.State
data Teletype m a where
ReadTTY :: Teletype m String
WriteTTY :: String -> Teletype m ()
SetState :: Integer -> Teletype m ()
makeSem ''Teletype
teletypeState :: Member (State Integer) r => Sem (Teletype ': r) a -> Sem r a
teletypeState = interpret \case
ReadTTY -> return ""
WriteTTY msg -> return ()
SetState n -> put n
teletypeIO :: Member (Embed IO) r => Sem (Teletype ': r) a -> Sem r a
teletypeIO = interpret \case
ReadTTY -> embed getLine
WriteTTY msg -> embed $ putStrLn msg
SetState n -> return ()
teletypeStateIO :: Members '[State Integer, Embed IO] r => Sem (Teletype ': r) a -> Sem r a
teletypeStateIO = interpret \case
ReadTTY -> embed getLine
WriteTTY msg -> embed $ putStrLn msg
SetState n -> put n
program :: Member Teletype r => Sem r ()
program = do
i <- readTTY
case i of
"" -> pure ()
_ -> do
setState (read i)
writeTTY i >> program
main :: IO ()
main = do
-- Interpret with State only
print $ run $ runState @Integer 0 $ teletypeState program
-- Interpret with IO only
runM $ teletypeIO program
-- Interpret with IO and State
result <- runM $ stateToIO @Integer 0 $ teletypeStateIO program
print result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment