Skip to content

Instantly share code, notes, and snippets.

@StephenWakely
Last active December 1, 2019 18:04
Show Gist options
  • Save StephenWakely/4b3a188cc41cf25819a0b0541c63f9f8 to your computer and use it in GitHub Desktop.
Save StephenWakely/4b3a188cc41cf25819a0b0541c63f9f8 to your computer and use it in GitHub Desktop.
Servant with Polysemy
{-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
-- |
module Main where
import Data.Aeson
import qualified Data.Text as T
import Polysemy (embed, Members, Sem, Member, Embed, interpret, runM, makeSem)
import Polysemy.IO
import GHC.Generics (Generic)
import Polysemy.Reader (Reader, runReader, ask)
import Network.Wai.Handler.Warp (run)
import Servant
newtype Name = Name T.Text
deriving (Show, Generic)
instance FromJSON Name
instance ToJSON Name
data Config = Config { name :: T.Text }
data Logger m a where
Loggit :: String -> Logger m ()
makeSem ''Logger
runLogger :: Member (Embed IO) r => Sem (Logger ': r) a -> Sem r a
runLogger = interpret $ \case
Loggit msg -> do
embed $ putStrLn msg
type Api = "name" :> Get '[JSON] Name
:<|> "name" :> ReqBody '[JSON] Name :> Post '[JSON] Name
routes :: Proxy Api
routes = Proxy
server :: Members '[Reader Config, Logger] r
=> ServerT Api (Sem r)
server = get :<|> post
where
get :: Members '[Reader Config, Logger] r => Sem r (Name)
get = do
loggit "Get da ponk"
c <- ask
return $ Name (name c)
post :: Member (Logger) r => Name -> Sem r (Name)
post ook = do
loggit "Set da ponk"
return $ Name "yay"
nt :: Sem '[Reader Config, Logger, Embed IO, Embed Handler] x
-> Servant.Handler x
nt m = runM $ embedToMonadIO @Servant.Handler $ runLogger $ runReader (Config { name = "ook" } ) m
mainServer :: ServerT Api Servant.Handler
mainServer = hoistServer routes nt server
app :: Application
app = serve routes mainServer
main :: IO ()
main = do
putStrLn "Starting on 3000"
run 3000 app
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment