registry-0.1.3.0: test/Test/Data/Registry/THSpec.hs
{-# LANGUAGE TemplateHaskell #-}
module Test.Data.Registry.THSpec where
import Data.Generics.Product.Typed
import Data.Registry.TH
import Protolude
import Universum ((...))
-- | Example of TemplateHaskell usage
-- | We define 2 low-level components: Logger and Tracer
-- We make the corresponding typeclasses
data Logger m = Logger {
-- a function taking 2 arguments
_info :: Text -> Text -> m ()
-- a function having a constraint
, _error :: forall a . (Monoid a) => a -> Text -> m ()
}
makeTypeclass ''Logger
newtype Tracer m = Tracer {
_traceIt :: Text -> m ()
}
makeTypeclass ''Tracer
-- | Now we make a component which is going to use both components
newtype Service m = Service {
doIt :: Int -> Text -> m ()
}
newService :: Monad m => Logger m -> Tracer m -> Service m
newService logger tracer = Service {
doIt = run ... implementService
} where
-- the typeclass instances can be resolved by using a Reader containing
-- a tuple with all the components
run = flip runReaderT (logger, tracer)
-- | Implement the service using typeclasses
implementService ::
Monad m
=> WithLogger m
=> WithTracer m
=> Int
-> Text
-> m ()
implementService n t = do
info "doing it" t
traceIt (show n)