registry-0.6.3.3: test/Test/Data/Registry/THSpec.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}
module Test.Data.Registry.THSpec where
import Data.Generics.Product.Typed
import Data.Registry.TH
import Protolude
-- * Example of TemplateHaskell usage to create the typeclass corresponding to a component
-- | 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 = \n t -> run (implementService n t)
}
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)