Skip to content

Instantly share code, notes, and snippets.

@LukaJCB
Last active September 22, 2019 13:01
Show Gist options
  • Save LukaJCB/c59b9e7b41bd1b12e5d4d3de683f6a5f to your computer and use it in GitHub Desktop.
Save LukaJCB/c59b9e7b41bd1b12e5d4d3de683f6a5f to your computer and use it in GitHub Desktop.
Alternative Tagless Final encoding in PureScript
module Algebra where
import Prelude
import Control.Monad.Eff (Eff)
import Data.Maybe (Maybe(..))
newtype ConsoleAlg f = ConsoleAlg
{ printLn :: String -> f Unit
, readLn :: f String
}
newtype KVStoreAlg f = KVStoreAlg
{ put :: String -> String -> f Unit
, get :: String -> f (Maybe String)
}
class ConsoleAlgC f where
printLn :: String -> f Unit
readLn :: f String
class KVStoreAlgC f where
put :: String -> String -> f Unit
get :: String -> f (Maybe String)
module Interpreter where
import Prelude
import Control.Monad.Eff (Eff)
import Data.Maybe (Maybe(..))
consoleInterpreter :: forall e. ConsoleAlg (Eff e)
consoleInterpreter = ConsoleAlg
{ printLn : \_ -> pure unit
, readLn : pure "John"
}
kvStoreInterpreter :: forall e. KVStoreAlg (Eff e)
kvStoreInterpreter = KVStoreAlg
{ put : \_ _ -> pure unit
, get : pure <<< Just
}
instance consoleInterpreterC :: ConsoleAlgC (Eff e) where
printLn _ = pure unit
readLn = pure "John"
instance kvStoreInterpreterC :: KVStoreAlgC (Eff e) where
put _ _ = pure unit
get = pure <<< Just
module Program where
import Prelude
import Control.Monad.Eff (Eff)
import Data.Maybe (Maybe(..))
program :: forall f. Bind f => ConsoleAlg f -> KVStoreAlg f -> f Unit
program (ConsoleAlg c) (KVStoreAlg k) = do
c.printLn "What's your name?"
name <- c.readLn
k.put "name" name
programC :: forall f. Bind f => ConsoleAlgC f => KVStoreAlgC f => f Unit
programC = do
printLn "What's your name?"
name <- readLn
put "name" name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment