diff --git a/consoledsl_done.hs b/consoledsl_done.hs new file mode 100644 index 0000000..d3a4459 --- /dev/null +++ b/consoledsl_done.hs @@ -0,0 +1,54 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE ScopedTypeVariables #-} + +import Polysemy +import Test.Hspec + +-- kind must be :: (* -> *) -> * -> * +data Console m a where + PrintLine :: String -> Console m () + ReadLine :: Console m String + +makeSem ''Console + +-- printLine :: Member Console r => String -> Sem r () +-- readLine :: Member Console r => Sem r a +-- run :: Sem '[] a -> a +-- runM :: Sem '[Embed m] a -> m a +-- embed :: Member (Embed m) r => m a -> Sem r a + +runConsoleIO :: Member (Embed IO) r => Sem (Console ': r) a -> Sem r a +runConsoleIO = interpret $ \case + PrintLine msg -> embed $ putStrLn msg + ReadLine -> embed $ getLine + +runConsolePure :: String -> Sem (Console ': r) a -> Sem r a +runConsolePure s = interpret $ \case + PrintLine msg -> pure () + ReadLine -> pure s + +spec :: Spec +spec = describe "program" $ do + it "adds 2 numbers given by user" $ do + let res = run . runConsolePure "7" $ program + res `shouldBe` (7 + 7) + +program :: Member Console r => Sem r Int +program = do + printLine "Insert number 1" + a <- readLine + printLine "Insert number 2" + b <- readLine + pure $ read a + read b + +main :: IO () +main = execute >>= print + where + execute = runM . runConsoleIO $ program